2

我有这样的表结构

PersonID   |  Name   |  ItemID1  |  ItemID2  |ItemID3  | ItemID4
1          |  kk     |   1       |  2        |NULL     | NULL
2          |  KK     |   1       |  NULL     | 2       | NULL

在上面的数据集中,如果两个人有相同的名字和相同的项目集(这里的项目序列不匹配),则他们是相同的。基本上,在第 1 行,人名是 KK,项目列表是 1 和 2,第 2 行也是如此。因此,这 2 个是匹配的行。

我需要编写一个 sql 查询来查找这些匹配的行吗?

4

2 回答 2

2

首先,这破坏了“数据规范化”,但也许您知道这一点并且需要基于某些约束来实现它,或者因为它通常对您的解决方案更容易。

这是一种解决方案(有很多):

首先在 VIEW 中使用 UNION ALL 查询来展平您的数据。让我们将此视图称为 viewFlattedPeopleWithItems (您也可以只使用临时表或虚拟表!):

SELECT PersonID, Name, ItemID1 as ItemID
FROM TABLE
UNION ALL
SELECT PersonID, Name, ItemID2
FROM TABLE
UNION ALL
SELECT PersonID, Name, ItemID3
FROM TABLE
UNION ALL
SELECT PersonID, Name, ItemID4
FROM TABLE

然后查找重复数据:

SELECT Name, Item, COUNT(*)
FROM viewFlattedPeopleWithItems
GROUP BY Name, Item
HAVING COUNT(*) > 1

如果需要,您还可以使用第二个查询来创建视图或临时表或类似的,然后加入联合所有查询以获取具有重复的 PersonID 值。

于 2013-10-14T03:12:13.097 回答
2

此查询将使列(itemID 列)的所有值在单个列中

   SELECT id,name,  case WHEN itemid1 IS NOT NULL THEN  CONVERT(varchar(10), itemid1) + ','
 else '' end  +  case WHEN itemid2 IS NOT NULL THEN  CONVERT(varchar(10), itemid2) + ',' else
 ''  end  +  case WHEN itemid3 IS NOT NULL THEN  CONVERT(varchar(10), itemid3) + ','  else '' 
end +  case WHEN itemid4 IS NOT NULL THEN  CONVERT(varchar(10), itemid4) + ','  else '' end  
 as itemid FROM emp

现在您必须编写一个函数来对 ItemID 列的逗号分隔值进行排序并返回字符串。仅此而已..现在您可以轻松进行完全匹配..但这不会提供良好的性能..

创建具有相同查询的计算列将使您获得性能..

于 2013-10-14T18:00:26.317 回答