0

嗨,我有一张下表说价格

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 } 

对于查询的第一部分,但无法得到我想要的结果,任何帮助将不胜感激。

谢谢

4

2 回答 2

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 天,因此没有重叠。

于 2013-10-10T03:24:03.573 回答
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
于 2013-10-10T03:50:37.400 回答