半棘手的SQL查询

时间:2008-10-22 16:00:22

标签: sql sql-server

我正在尝试为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发生了

请注意,它为每个类别返回一行,并且它是该类别具有最高优先级的行。

有谁能告诉我如何编写此查询?

8 个答案:

答案 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