设置列 SQL 的 Over Partition
Posted
技术标签:
【中文标题】设置列 SQL 的 Over Partition【英文标题】:Over Partition for set column SQL 【发布时间】:2021-10-19 21:49:02 【问题描述】:我有这张表,我需要设置 ID 列 = 1 列分钟的最大值,其余 ID 列 = 0。
初始表:
Register |minutes | ID
10 |5 | 0
10 |6 | 0
10 |0 | 0
12 |3 | 0
12 |0 | 0
12 |4 | 0
决赛桌:
Register |minutes | ID
10 |5 | 0
10 |6 | 1
10 |0 | 0
12 |3 | 0
12 |0 | 0
12 |4 | 1
使用 Over Partition,有什么想法吗?
UPDATE A
SET ID = 1
FROM
(
Select top 1 row_number() over (PARTITION BY minutes
order by minutes asc) AS column,*
from table
)A
WHERE A.column=1
【问题讨论】:
请标记您的 DBMS。并非所有这些都允许更新子查询。 当你总是可以在运行时计算它时为什么要存储它(如果任何其他行发生变化,不必担心更新存储的值)。 【参考方案1】:您可以在可更新的 CTE 中使用 row_number():
with m as (
select *,
row_number() over(partition by register order by minutes desc) rn
from t
)
update m set id=1 where rn=1
【讨论】:
【参考方案2】:这是你想要的吗?
DECLARE @max INT
SELECT TOP 1
@max = Minutes
FROM YourTable
ORDER BY Minutes DESC
UPDATE YourTable
SET ID = CASE
WHEN Minutes = @max
THEN 1
ELSE 0
END
【讨论】:
我需要分组或分区,因为它是寄存器和分钟列的组合(请观看更新)【参考方案3】:如果您不想使用 CTE 或变量表:
UPDATE A
SET A.ID = CASE
WHEN B.RowNumber = 1
THEN 1
ELSE 0
END
FROM table A
JOIN (
SELECT *, row_number() over (PARTITION BY Register
order by minutes DESC) AS RowNumber
FROM table
) B ON A.Register = B.Register AND A.minutes = B.minutes
【讨论】:
为什么要重新加入,可以直接更新B
【参考方案4】:
我保留了我之前的答案,因为它代表了问题的答案,就像在回答时一样。鉴于添加到问题中的新信息,更新查询如下:
;WITH MyCTE AS
(
SELECT Register,
Minutes,
ID,
ROW_NUMBER() OVER (PARTITION BY Register ORDER BY Minutes DESC) RowN
FROM YourTable
)
UPDATE MyCTE
SET ID = CASE
WHEN RowN = 1 THEN 1
ELSE 0
END
【讨论】:
以上是关于设置列 SQL 的 Over Partition的主要内容,如果未能解决你的问题,请参考以下文章
基于 OVER PARTITION BY 子句的 SQL 计算列
在 SQL Server 2005 中使用 ROW_NUMBER() OVER () 对不同列进行排序的分页查询