SQL在表中显示重复值

时间:2012-09-20 09:52:11

标签: sql sql-server sql-server-2008

我需要获得一个查询,该查询将显示错误捕获的具有相同银行详细信息的人员的详细信息。

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

1stName   1stAccNo   1stItemSold    2ndName   2ndAccNo  2ndItemSold
Albert    2231432     Item1         John      2231432   Item3
Robert    6321009     Item11        Peter     6321009   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 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分: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