给出一个名为Answers的(简化)表,如
Id Person Answer Priority
1 Tom France Low
2 Tom Germany High
3 Fred England Low
4 Amy Italy High
我想编写一个SQL查询,每个人返回一行,表明他们的最高优先级答案。我的想法是使用自我加入
SELECT *
FROM Answers aLow
LEFT OUTER JOIN Answers aHigh
ON aLow.Person = aHigh.Person
AND aLow.Priority = 'Low'
AND aHigh.Priority = 'High'
然后在代码中检查哪些优先级列是非空的,但是为Tom
返回一个额外的行Id Person Answer Priority Id Person Answer Priority
1 Tom France Low 2 Tom Germany High
2 Tom Germany High NULL NULL NULL NULL
3 Fred England Low NULL NULL NULL NULL
4 Amy Italy High NULL NULL NULL NULL
使用这种方法,所需的输出将是
Id Person Answer Priority Id Person Answer Priority
1 Tom France Low 2 Tom Germany High
3 Fred England Low NULL NULL NULL NULL
4 Amy Italy High NULL NULL NULL NULL
我确信我必须遗漏一些简单的东西,但不能指责它。
我错过了什么?有没有更好的方法来解决这个问题?
答案 0 :(得分:1)
您可以使用带有ROW_NUMBER
窗口函数的公用表表达式:
WITH cte
AS (SELECT [id],
[person],
[answer],
[priority],
RN = Row_number()
OVER (
partition BY person
ORDER BY CASE WHEN priority = 'High' THEN 0 ELSE 1 END
ASC)
FROM dbo.answers)
SELECT [id],
[person],
[answer],
[priority]
FROM cte
WHERE rn = 1
ID PERSON ANSWER PRIORITY
4 Amy Italy High
3 Fred England Low
2 Tom Germany High
答案 1 :(得分:1)
这是一种方法:
with priorityRank as
(
select *
, priorityRank = row_number() over (partition by Person
order by case Priority when 'High' then 1 when 'Low' then 2 end
, Id)
from
Answers
)
select Id
, Person
, Answer
, Priority
from priorityRank
where priorityRank = 1
答案 2 :(得分:0)
您是否尝试使用DISTINCT:
SELECT DISTINCT id, Person,Answer, Priority
FROM Answers aLow
LEFT OUTER JOIN Answers aHigh
ON aLow.Person = aHigh.Person
AND aLow.Priority = 'Low'
AND aHigh.Priority = 'High'
答案 3 :(得分:0)
如果我正确理解你,你应该从
获得理想的结果SELECT *
FROM (SELECT * FROM Answers WHERE Priority = 'Low') aLow
FULL JOIN (SELECT * FROM Answers WHERE Priority = 'High') aHigh
ON aLow.Person = aHigh.Person