SQL显示3行中具有重复值的行

时间:2013-10-10 02:45:49

标签: sql sql-server-2005

您好我有下表说价格

CostID   ItemID  Level  EffectiveFrom EffectiveTo            
6274751  12345   1       12/02/2013   NULL
6274751  12345   1       13/02/2013   NULL
6274751  12345   2       12/02/2013   NULL
6254784  12345   1       12/02/2013   NULL
6254784  12345   1       13/02/2013   NULL
6244784  12345   9       12/02/2013   NULL

我希望能够通过比较3列'CostID''ItemID'和'Level'来编写查询来查找重复行,并显示仅重复的行

预期产出第1部分

CostID   ItemID  Level  EffectiveFrom EffectiveTo            
6274751  12345   1       12/02/2013   NULL
6274751  12345   1       13/02/2013   NULL
6254784  12345   1       12/02/2013   NULL
6254784  12345   1       13/02/2013   NULL

一旦我得到上面的结果,我想从最后一个重复行

更新EffectiveTo表

第2部分的预期产出

CostID   ItemID  Level  EffectiveFrom EffectiveTo            
6274751  12345   1       12/02/2013   13/02/2013
6274751  12345   1       13/02/2013   NULL
6254784  12345   1       12/02/2013   13/02/2013
6254784  12345   1       13/02/2013   NULL

我试过了:

{
SELECT *
FROM price
WHERE ItemID IN
    (     SELECT ItemID
          FROM price
          GROUP BY ItemId          HAVING COUNT(distinct level) > 1
    )
ORDER BY CostID } 

对于查询的第一部分但无法获得我想要的结果,我们将非常感谢任何帮助。

由于

2 个答案:

答案 0 :(得分:1)

这将为您提供重复的行:

select distinct p.*
from price p
join price q
    on p.CostID = q.CostID
    and p.ItemID = q.ItemID
    and p.Level = q.Level
    and p.EffectiveFrom != q.EffectiveFrom

条件p.EffectiveFrom != q.EffectiveFrom很重要,因为它会停止所有加入自身的行。通常,您只需比较不等式的id列,但您的表似乎没有。


使用合适的结束日期更新旧行:

update p set
p.EffectiveTo = dateadd(day, -1, q.EffectiveFrom)
from price p
join price q
    on p.CostID = q.CostID
    and p.ItemID = q.ItemID
    and p.Level = q.Level
    and p.EffectiveFrom < q.EffectiveFrom

与此查询唯一真正的区别是将不等式更改为小于,因此仅选择更新那些较早的行。

请注意,我已从较晚的日期减去1天,因此没有重叠。

答案 1 :(得分:0)

这个有点长......但你可以做一些改进。

;WITH cte AS
(
    SELECT ROW_NUMBER() OVER (PARTITION BY CostID, ItemID, Level ORDER BY CostID, EffectiveFrom) AS RNUM,
        CostID,
        ItemID,
        Level,
        EffectiveFrom,
        EffectiveTo
    FROM @Price
),
cteDup AS 
(
    SELECT DISTINCT CostID, ItemID, Level FROM cte WHERE RNUM > 1
)
SELECT tt.* FROM @Price tt
INNER JOIN cteDup cc ON tt.CostID = cc.CostID AND tt.ItemID = cc.ItemID AND tt.Level = cc.Level

更新:这将进行直接更新,不确定这是否是您想要的。

;WITH cte AS
(
    SELECT ROW_NUMBER() OVER (PARTITION BY CostID, ItemID, Level ORDER BY CostID, EffectiveFrom) AS RNUM,
        CostID,
        ItemID,
        Level,
        EffectiveFrom,
        EffectiveTo
    FROM @Price
)
UPDATE c1 SET 
     EffectiveTo = c2.EffectiveFrom
FROM cte c1
INNER JOIN cte c2 ON c1.CostID = c2.CostID  AND c1.ItemID = c2.ItemID AND c1.Level = c2.Level AND c1.RNUM + 1 = c2.RNUM