我发布了一个问题this,我现在需要执行该问题。我编辑了几次以符合当前的要求,现在我想我会更清楚地作为我的最终解决方案。
我的表:
Items | Price | UpdateAt
1 | 2000 | 02/02/2015
2 | 4000 | 06/04/2015
1 | 2500 | 05/25/2015
3 | 2150 | 07/05/2015
4 | 1800 | 07/05/2015
5 | 5540 | 08/16/2015
4 | 1700 | 12/24/2015
5 | 5200 | 12/26/2015
2 | 3900 | 01/01/2016
4 | 2000 | 06/14/2016
正如您所看到的,这是一张在上次更新之前保留商品价格和旧价格的表格。
现在我需要找到以下行:
为什么那些条件?因为我需要从那些超过1年的记录中对该表进行清理,同时仍然保留完整的项目列表。
因此,根据这些条件,上表的结果应为:
Items | Price | UpdateAt
1 | 2000 | 02/02/2015
2 | 4000 | 06/04/2015
4 | 1800 | 07/05/2015
应选择项目1的02/02/2015更新,而更新编号为。 2 2015年5月25日,虽然仍然超过1岁,但不应该因为它是第1项的最新价格。 项目3不在列表中,因为它从未更新,因此它的价格保持不变,所以我不需要清理它。
起初我觉得它不会那么难,我想我已经有了答案但是在我继续进行的时候,它已经不再容易了。
我需要一个有效清理表的解决方案 - 如果它可以产生我需要的相同结果,则无需遵循上述3个条件:需要删除的记录。
答案 0 :(得分:2)
试试这个,
DECLARE @Prices TABLE(Items INT, Price DECIMAL(10,2), UpdateAt DATETIME)
INSERT INTO @Prices
VALUES
(1, 2000, '02/02/2015')
,(2, 4000, '06/04/2015')
,(1, 2500, '05/25/2015')
,(3, 2150, '07/05/2015')
,(4, 1800, '07/05/2015')
,(5, 5540, '08/16/2015')
,(4, 1700, '12/24/2015')
,(5, 5200, '12/26/2015')
,(2, 3900, '01/01/2016')
,(4, 2000, '06/14/2016')
SELECT p.Items, p.Price, p.UpdateAt
FROM @Prices p
LEFT JOIN ( SELECT
p1.Items,
p1.UpdateAt,
ROW_NUMBER() OVER (PARTITION BY p1.Items ORDER BY p1.UpdateAt DESC) AS RowNo
FROM @Prices p1
) AS hp ON hp.Items = p.Items
AND hp.UpdateAt = p.UpdateAt
WHERE hp.RowNo > 1 -- spare one price for each item at any date
AND p.UpdateAt < DATEADD(YEAR, -1, GETDATE()) -- remove only prices older than a year
结果是:
Items Price UpdateAt
----------- --------------------------------------- -----------------------
1 2000.00 2015-02-02 00:00:00.000
2 4000.00 2015-06-04 00:00:00.000
4 1800.00 2015-07-05 00:00:00.000
答案 1 :(得分:1)
此查询将返回您正在寻找的数据集:
SELECT t1.Items, t1.Price, t1.UpdateAt
FROM
(
SELECT
t2.Items,
t2.Price,
t2.UpdateAt,
ROW_NUMBER() OVER (PARTITION BY t2.Items ORDER BY t2.UpdateAt DESC) AS rn
FROM [Table] AS t2
) AS t1
WHERE t1.rn > 1
AND t1.UpdateAt < DATEADD(year, -1, GETDATE())