我有一个方案来更新行 在相同条件下(状态= 1),但不是最新行。 这就是表格设计。
--------------------------------------------------
|idx | status | var1 | date
--------------------------------------------------
| 2 | 1 | cat | 2018-06-17 15:41:32.110
| 3 | 1 | dog | 2018-06-17 11:41:32.110
| 2 | 1 | lamb | 2018-06-17 11:41:32.110
| 2 | 1 | pc | 2018-06-17 09:41:32.110
| 3 | 1 | doll | 2018-06-17 09:41:32.110
我想要得到所有相同的条件 其中idx等于且status = 1,并且 将状态更新为0(最近的行除外)。 在这种情况下,有3行IDx为2,状态= 1 和2行,其idx为3,状态= 1。 查询后,表格应如下图所示
--------------------------------------------------
|idx | status | var1 | date
--------------------------------------------------
| 2 | 1 | cat | 2018-06-17 15:41:32.110
| 3 | 1 | dog | 2018-06-17 11:41:32.110
| 2 | 0 | lamb | 2018-06-17 11:41:32.110
| 2 | 0 | pc | 2018-06-17 09:41:32.110
| 3 | 0 | doll | 2018-06-17 09:41:32.110
我不知道该怎么做,并至少尝试显示 具有多个等于1个相等条件并提出此查询的行
select Idx, status, COUNT(Idx) as count from table
group by Idx, status
having COUNT(Idx) > 1 and status = 1
order by Idx
这显示我在相同条件下有多少行, 但我也想让行显示var1和日期 但我不知道该怎么做。
在进行.Net开发时,我可以列出idx 到列表并在每个idx上执行for循环,并在该for循环中进行更新, 但是我很想学习更多有关sql的知识,以及如何解决这个问题。
答案 0 :(得分:4)
我们可以尝试使用CTE进行更新:
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY idx ORDER BY date DESC) rn
FROM yourTable
)
UPDATE cte
SET status = 0
WHERE rn > 1 AND status = 1;
答案 1 :(得分:0)
您也可以在没有CTE的情况下实现它:
UPDATE t SET status = 0 FROM tbl t WHERE NOT EXISTS
( SELECT 1 FROM tbl GROUP BY idx HAVING MAX(date)=t.date AND idx=t.idx );
请参阅此处:http://rextester.com/BVAS22315
Tim和我的解决方案之间的区别在于,如果两个记录具有相同的idx
,并且日期完全相同,则Tim的命令将只保留一个记录不变(status=1
),而我的命令会使它们都保持不变。
然后,使用窗口功能ROW_NUMBER()
,您也可以像这样:
UPDATE t SET status=0 FROM
(SELECT *, ROW_NUMBER() OVER (PARTITION BY idx ORDER BY date DESC) rn
FROM tbl) t
WHERE rn>1
第二个版本的行为与Tim的解决方案完全相同,请参见此处:http://rextester.com/MFRAMR93418
(请注意,“狗”和“羔羊”的日期相同,只有一个更新。)