2012-09-20 149 views
1

我需要获得一个查询,该查询将显示具有相同银行详细信息且已被错误捕获的人员的详细信息。SQL在表中显示重复值

我需要然后显示正确的细节以及这些人的不正确的细节。例如:

 
1stName 1stAccNo 1stItemSold 2ndName 2ndAccNo 2ndItemSold 
Albert 2231432  Item1   John  2231432 Item3 
Robert09  Item11  Peter09 Item3 

名称和AccNo在一张桌子上,而ItemSold在不同的桌子上。

我有以下查询:

select p1.Name As 1stName, p1.AccNo AS 1stAccNo, I.ItemSold AS 1stItemSold, p2.Name AS 2ndName, p2.AccNo AS 2ndAccNo, I.ItemSold As 2ndItemSold 
FROM Persons p1 JOIN Persons p2 ON p1.AccNo = p2.AccNo 
INNER JOIN Items I on p.ItemID = I.ItemID 

的问题是,第二ItemSold是不正确的,因为它是一样的1stItemSold。我该如何改变我的查询,以便我可以获得正确的结果?

+2

什么样的SQL?你只有向人们出售2件物品? – podiluska

+0

SQL Server 2008.不,问题是,有时候,超过2人拥有相同的帐号。我找到的一个例子是具有相同帐号的8人。 – user1668123

+0

@ user1668123你能提供这两个表的一些示例数据吗?或者更好的创建一个[SQL小提琴](http://sqlfiddle.com/)与工作数据模型 – Taryn

回答

1

您应该将项目加入第二个表格。此外,如果你需要不同的人,你必须包含where p1.id<>p2.id其中ID是在人员表的主键

select 
p1.Name As 1stName, p1.AccNo AS 1stAccNo, I1.ItemSold AS 1stItemSold, 
p2.Name AS 2ndName, p2.AccNo AS 2ndAccNo, I2.ItemSold As 2ndItemSold 
FROM Persons p1 JOIN Persons p2 ON p1.AccNo = p2.AccNo 
INNER JOIN Items I1 on p1.ItemID = I1.ItemID 
INNER JOIN Items I2 on p2.ItemID = I2.ItemID 
where p1.id<>p2.id 

PS:基于评论。返回最后ItemSold避免重复:

select 
p1.Name As 1stName, p1.AccNo AS 1stAccNo, I1.ItemSold AS 1stItemSold, 
p2.Name AS 2ndName, p2.AccNo AS 2ndAccNo, I2.ItemSold As 2ndItemSold 
FROM Persons p1 JOIN Persons p2 ON p1.AccNo = p2.AccNo 
left JOIN 
    (select ItemID,ItemSold, 
      row_number() over (PARTITION BY ItemID order by DATE_SOLD DESC) as rn 
    from Items) I1 
     on (p1.ItemID = I1.ItemID) and (rn=1) 
left JOIN 
    (select ItemID,ItemSold, 
      row_number() over (PARTITION BY ItemID order by DATE_SOLD DESC) as rn 
    from Items) I2 
     on (p2.ItemID = I2.ItemID) and (rn=1) 

where p1.id<>p2.id 
+0

我试过了,但我从该查询中得到不必要的重复结果。 – user1668123

+0

这是因为你有一个人以上的物品。所以你应该决定在这种情况下做什么。 – valex

+0

如果一个人有多个物品,那么我需要根据购买日期返回购买的第一个物品。 – user1668123

1

我可能会误解你的要求,但它听起来像是你可以使用UNPIVOT/PIVOT功能得到你需要的结果。

如果您知道要转换的列数,那么您可以对此静态版本进行硬编码。

select * 
from 
(
    select AccNo, 
    val, 
    col + cast(rn as varchar(10)) Col_Name 
    from 
    (
    select p1.accno, 
     p1.name, 
     p1.itemid, 
     i1.id, 
     i1.i_name, 
     row_number() over(partition by accno order by name) rn 
    from persons p1 
    left join items i1 
     on p1.itemid = i1.id 
) x 
    unpivot 
    (
    val 
    for col in (name, i_name) 
) u 
) x1 
pivot 
(
    max(val) 
    for col_name in ([name1], [i_name1], [name2], [i_name2]) 
) p 

看到SQL Fiddle with Demo

但它听起来像是你将有数目不详的项目转变为列,因此你可以使用动态SQL和创造的这一动态的版本:

DECLARE @colsUnPivot AS NVARCHAR(MAX), 
    @colsPivot AS NVARCHAR(MAX), 
    @query AS NVARCHAR(MAX) 

SET @colsUnPivot = stuff((select ','+C.name 
     from sys.columns as C 
     where (C.object_id = object_id('persons') 
        or C.object_id = object_id('items')) 
      and C.name like '%name%' 
     for xml path('')), 1, 1, '') 

select @colsPivot = STUFF((SELECT ',' 
         + quotename(c.name 
         + cast(p.rn as varchar(10))) 
        from 
        (
         select row_number() over(partition by accno order by name) rn 
         from persons 
        ) p 
        cross apply 
         sys.columns as C 
        where (C.object_id = object_id('persons') 
          or C.object_id = object_id('items')) 
         and C.name like '%name%' 
        group by c.name, p.rn 
        order by p.rn, c.name desc 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

set @query 
    = 'select * 
     from 
     (
      select AccNo, 
      val, 
      col + cast(rn as varchar(10)) Col_Name 
     from 
     (
      select p1.accno, 
      p1.name, 
      p1.itemid, 
      i1.id, 
      i1.i_name, 
      row_number() over(partition by accno order by name) rn 
      from persons p1 
      left join items i1 
      on p1.itemid = i1.id 
     ) x 
     unpivot 
     (
      val 
      for col in ('+ @colsunpivot +') 
     ) u 
    ) x1 
     pivot 
     (
     max(val) 
     for col_name in ('+ @colsPivot + ') 
    )p' 

exec(@query) 

请参阅SQL Fiddle with Demo

+0

我试着复制你在上面的查询中做了什么,但是当涉及到pivot/unpivot时,我很失落。有没有更简单的方法来做到这一点? – user1668123

+0

@ user1668123如果您的列数量未知,我无法看到另一种方式来执行此操作。如果您对于pivot/unpivot是如何工作的具体问题,请询问,我会澄清它。 – Taryn

+0

@ user1668123我不这样做,但是您总是可以使用[SQL Fiddle](http://sqlfiddle.com/)来创建您的数据模型。 – Taryn