我很不擅长解释,所以让我试着阐述一下我的问题。我有一个类似于以下内容的表格:
Source Value User
======== ======= ======
old1 1 Phil
new 2 Phil
old2 3 Phil
new 4 Phil
old1 1 Mike
old2 2 Mike
new 1 Jeff
new 2 Jeff
我需要做的是创建一个查询,根据源和值获取用户的值。它应该遵循以下规则:
For every user, get the highest value. However, disregard the 'new' source if either 'old1' or 'old2' exists for that user.
因此,根据这些规则,我的查询应从该表返回以下内容:
Value User
======= ======
3 Phil
2 Mike
2 Jeff
我提出了一个与所要求的内容接近的查询:
SELECT MAX([Value]), [User]
FROM
(
SELECT CASE [Source]
WHEN 'old1' THEN 1
WHEN 'old2' THEN 1
WHEN 'new' THEN 2
END AS [SourcePriority],
[Value],
[User]
FROM #UserValues
) MainPriority
WHERE [SourcePriority] = 1
GROUP BY [User]
UNION
SELECT MAX([Value]), [User]
FROM
(
SELECT CASE [Source]
WHEN 'old1' THEN 1
WHEN 'old2' THEN 1
WHEN 'new' THEN 2
END AS [SourcePriority],
[Value],
[User]
FROM #UserValues
) SecondaryPriority
WHERE [SourcePriority] = 2
GROUP BY [User]
但是这会返回以下结果:
Value User
======= ======
3 Phil
4 Phil
2 Mike
2 Jeff
显然,Phil=4 的额外值是不需要的。我应该如何尝试修复此查询?我也知道这是一个相当复杂的解决方案,并且通过正确使用聚合可能可以更轻松地解决它,但是我对聚合还不太熟悉,这导致我诉诸联合。本质上,我正在寻求帮助来创建尽可能简洁的解决方案。
如果有人想自己填充表来尝试一下,这里是 SQL 代码:
CREATE TABLE #UserValues
(
[Source] VARCHAR(10),
[Value] INT,
[User] VARCHAR(10)
)
INSERT INTO #UserValues VALUES
('old1', 1, 'Phil'),
('new', 2, 'Phil'),
('old2', 3, 'Phil'),
('new', 4, 'Phil'),
('old1', 1, 'Mike'),
('old2', 2, 'Mike'),
('new', 1, 'Jeff'),
('new', 2, 'Jeff')
最佳答案
您可以相当轻松地解决这个问题,而无需借助窗口函数。在这种情况下,您需要最大值,其中((不是新的)OR(没有 old1 或 old2 条目))。
下面是一个可以正确处理示例数据的查询:
SELECT
MAX(U1.[Value]) as 'Value'
,U1.[User]
FROM
#UserValues U1
WHERE
U1.[Source] <> 'new'
OR NOT EXISTS (SELECT * FROM #UserValues U2 WHERE U2.[User] = U1.[User] AND U2.[Source] IN ('old1','old2'))
GROUP BY U1.[User]
关于sql - 尝试在不使用 UNION 的情况下简化 SQL 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53398354/