根据其他行的值更新列[关闭]
Posted
技术标签:
【中文标题】根据其他行的值更新列[关闭]【英文标题】:Updating a column based on values from other rows [closed] 【发布时间】:2011-09-06 21:23:10 【问题描述】:我有下表:
Id CategoryId Code Status
=================================
1 A100 0012 NULL
2 A100 0012 NULL
3 A100 0055 NULL
4 A100 0012 NULL
5 B201 1116 NULL
6 B201 1116 NULL
7 B201 1121 NULL
8 B201 1024 NULL
逻辑: 1.相同的CategoryID,代码应该相同。 2. 如果存在多个代码,则考虑值最低的一个。
想要的结果:
Id CategoryId Code Status
=================================
1 A100 0012 NULL
2 A100 0012 NULL
3 A100 0055 FAIL
4 A100 0012 NULL
5 B201 1116 FAIL
6 B201 1116 FAIL
7 B201 1121 FAIL
8 B201 1024 NULL
谢谢
【问题讨论】:
什么意思;它不允许你写代码? @Ben_53:“如果相同 categoryid 的代码不同,则失败,否则为 NULL” - 你怎么知道哪个是“正确”的 categoryid? @Abe 我相信所需的输出是相应地设置Status
列
业务逻辑说“所有类别 ID 必须具有相同的代码” 数据中的敌人示例,id = 3 具有相同类别 ID 的不同代码。
@Ben 假设你有两行,id=10, categoryID=ABCD, Code=xy11
和 id=11, categoryID=ABCD, Code=ab52
。其中哪一个是“正确”的?
【参考方案1】:
在您的编辑之后...
DECLARE @T TABLE
(
ID INT,
CategoryID CHAR(4),
Code CHAR(4),
Status CHAR(4) NULL
)
INSERT INTO @T (ID,CategoryID, Code)
SELECT 1,'A100',0012 UNION ALL SELECT 2,'A100',0012 UNION ALL
SELECT 3,'A100',0055 UNION ALL SELECT 4,'A100',0012 UNION ALL
SELECT 5,'B201',1116 UNION ALL SELECT 6,'B201',1116 UNION ALL
SELECT 7,'B201',1121 UNION ALL SELECT 8,'B201',1024;
WITH T AS
(
SELECT *, MIN(Code) OVER (PARTITION BY CategoryID ) AS MinCode
from @T
)
UPDATE T
SET Status = 'FAIL'
WHERE Code <> MinCode
SELECT *
FROM @T
返回
ID CategoryID Code Status
----------- ---------- ---- ------
1 A100 12 NULL
2 A100 12 NULL
3 A100 55 FAIL
4 A100 12 NULL
5 B201 1116 FAIL
6 B201 1116 FAIL
7 B201 1121 FAIL
8 B201 1024 NULL
【讨论】:
【参考方案2】:我要试一试,虽然我真的认为这应该是一个新问题。
;WITH o AS
(
SELECT Id, CategoryId, Code, Status,
rn = ROW_NUMBER() OVER (PARTITION BY CategoryId ORDER BY Id)
FROM dbo.my_table
),
n AS
(
SELECT CategoryId, Code
FROM o WHERE rn = 1
)
UPDATE o
SET [Status] = 'FAILURE'
FROM o INNER JOIN n
ON o.CategoryId = n.CategoryId
AND o.Code <> n.Code
WHERE o.rn > 1;
【讨论】:
以上是关于根据其他行的值更新列[关闭]的主要内容,如果未能解决你的问题,请参考以下文章
在 LibreOffice 或其他电子表格工具中应用基于行的过滤器而不是基于列的过滤器