我正在尝试为SQL Server 2005编写查询,但我无法弄清楚如何执行此操作。我有一个包含以下字段的表:
MessageID int
CategoryID int
优先权tinyint
MessageText NVARCHAR(MAX)
我需要一个查询,它将为类别中具有最高优先级的每一行返回*。例如,如果我有以下数据:
MessageID,CategoryID,Priority,MessageText
1,100,1,错误#1234发生了
2,100,2,错误#243发生了
3,100,3,错误#976发生了
4,200,4,错误#194发生了
5,200,1,错误#736发生了
6,300,3,错误#54发生了
7,300,2,错误#888发生了
然后结果将是:
MessageID,CategoryID,Priority,MessageText
3,100,3,错误#976发生了
4,200,4,错误#194发生了
6,300,3,错误#54发生了
请注意,它为每个类别返回一行,并且它是该类别具有最高优先级的行。
有谁能告诉我如何编写此查询?
答案 0 :(得分:6)
验证
SELECT
highest_priority_messages.*
FROM
(
SELECT
m.MessageID
, m.CategoryID
, m.Priority
, m.MessageText
, Rank() OVER
(PARTITION BY m.CategoryID ORDER BY m.Priority DESC) AS p_rank
FROM [Message] m
GROUP BY
m.CategoryID
, m.Priority
, m.MessageID
, m.MessageText
) highest_priority_messages
WHERE
p_rank = 1
答案 1 :(得分:1)
我认为这应该有用,表名称假定为消息
SELECT
M.MessageId,
M.CategoryId,
M.Priority,
M.MessageText
FROM
(
SELECT
CategoryId,
MAX(Priority) AS Priority
FROM Messages
GROUP BY CategoryId
) AS MaxValues
INNER JOIN Messages M
ON (MaxValues.CategoryId = M.CategoryId
AND MaxValues.Priority = M.Priority)
注意强>
此方法中唯一的“问题”是,如果您有多个最高优先级......
答案 2 :(得分:1)
如果你想在没有所有子查询的情况下这样做:
SELECT
MessageID,
CategoryID,
Priority,
MessageText
FROM
dbo.Messages M1
LEFT OUTER JOIN dbo.Messages M2 ON
M2.CategoryID = M1.CategoryID AND
M2.Priority > M1.Priority
WHERE
M2.MessageID IS NULL
您可能需要根据处理关系的方式调整查询。你没有这样的例子,所以我不确定。
答案 3 :(得分:1)
select distinct query1.* from
(select categoryId,msgText,max(priorityId) as MAX_PRIORITY
from message
group by categoryId,msgText
order by categoryId
) query1,
(select categoryId,max(priorityId) as MAX_PRIORITY
from message
group by categoryId
order by categoryId
) query2
where query1.MAX_PRIORITY = query2.MAX_PRIORITY
order by query1.categoryId
答案 4 :(得分:0)
SELECT
Messages.MessageID
, Messages.CategoryID
, Messages.Priority
, Messages. MessageText
FROM
Messages
INNER JOIN
(
SELECT
CategoryID
, MAX(Priority) AS Priority
FROM
Messages
GROUP BY
CategoryID
) AS MaxResults
ON
(
Messages.CategoryID = MaxResults.CategoryID
AND
Messages.Priority = MaxResults.Priority
)
看起来这与上面给出的答案基本相同......使用相同的警告。
虽然这个可以直接使用。
答案 5 :(得分:0)
这更短,更容易阅读(imo)。
select ms.*
from
messages ms
,(
select ms1.categoryid, max(ms1.priority) as max_priority
from messages ms1
group by ms1.categoryid
) tmp
where ms.categoryid = tmp.categoryid
and ms.priority = tmp.max_priority;
答案 6 :(得分:0)
我发表评论的排名还不够高,所以我想补充一下cfeduke的解决方案:
SELECT
highest_priority_messages.*
FROM
(
SELECT
m.MessageID
, m.CategoryID
, m.Priority
, m.MessageText
, Rank() OVER
(PARTITION BY m.CategoryID ORDER BY m.Priority DESC, m.MessageID DESC) AS p_rank
FROM [Message] m
GROUP BY
m.CategoryID
, m.Priority
, m.MessageID
, m.MessageText
) highest_priority_messages
WHERE
p_rank = 1
如果您添加另一个具有优先级3的CategoryID 100消息,原始解决方案将带回2行,通过添加另一个订单条件,我们消除了两个项目排名相同的可能性。
这是我插入的一行的副本来测试它。
insert into [Message] (MessageID, CategoryID, Priority, MessageText)
select 8, 100, 3, 'Error #976-2 occurred'
答案 7 :(得分:0)
SELECT DISTINCT CategoryId,PS.Priority,MessageID,MessageText
FROM Priority_Scene PS
JOIN (SELECT MAX(Priority) AS Priority FROM Priority_Scene GROUP BY CategoryId) A
ON A.Priority = PS.Priority