合并来自不同用户的优先级记录时使用ORDER BY

时间:2017-11-20 20:45:06

标签: sql sql-server

我遇到了复杂的“ORDER BY”问题,这也是一个很难解释的问题(也可能不太可能!)。

假设我有2个客户,每个客户提出3张支持票据(进入SQL数据库),之后为每个客户设置优先级。两个结果集看起来像这样(按优先级排序):

USER   | SUBJECT | PRIORITY   | DATESTAMP
-------+---------+------------+----------------
THOMAS | Error A | Priority 1 | 20/11/2017 08:01
THOMAS | Error C | Priority 2 | 20/11/2017 10:30
THOMAS | Error B | Priority 3 | 20/11/2017 14:55

USER   | SUBJECT | PRIORITY   | DATESTAMP
-------+---------+------------+----------------
HENRY  | Error B | Priority 1 | 20/11/2017 11:14
HENRY  | Error A | Priority 2 | 20/11/2017 18:44
HENRY  | Error C | Priority 3 | 20/11/2017 16:26

这就是它变得复杂的地方(我认为):让我们说我想组合这些列表来创建支持票据的“主列表”,按顺序排序以为技术人员创建任务列表。此ORDER BY需要使用Datestamp来确保先解决先前的故障单,但也要遵守用户分配的优先级编号,以便在其他人之前处理更重要的工作。结果表应如下所示:

USER   | SUBJECT | PRIORITY   | DATESTAMP
-------+---------+------------+----------------
THOMAS | Error A | Priority 1 | 20/11/2017 08:01
THOMAS | Error C | Priority 2 | 20/11/2017 10:30
HENRY  | Error B | Priority 1 | 20/11/2017 11:14
THOMAS | Error B | Priority 3 | 20/11/2017 14:55
HENRY  | Error A | Priority 2 | 20/11/2017 18:44
HENRY  | Error C | Priority 3 | 20/11/2017 16:26

目前,我正在努力实现这一目标。

如果我首先按日期时间字段对它们进行排序,则基本上会忽略优先级,因为所有日期都不同。

如果我先按优先级字段对它们进行排序,我会得到:

USER   | SUBJECT | PRIORITY   | DATESTAMP
-------+---------+------------+----------------
THOMAS | Error A | Priority 1 | 20/11/2017 08:01
HENRY  | Error B | Priority 1 | 20/11/2017 11:14
THOMAS | Error C | Priority 2 | 20/11/2017 10:30
HENRY  | Error A | Priority 2 | 20/11/2017 18:44
THOMAS | Error B | Priority 3 | 20/11/2017 14:55
HENRY  | Error C | Priority 3 | 20/11/2017 16:26

这里的问题是亨利的门票在名单上的位置太高了 - 他的优先级1应该在托马斯的优先级1和2之后,因为它是在以后记录的。

我觉得这不能通过简单地重新排列ORDER BY中字段的顺序来解决,如果它可以完成,但我想不出有办法解决它。是否有一些特殊的多层方法可以实现这一目标,还是我只是愚蠢?谢谢!

3 个答案:

答案 0 :(得分:0)

好吧,我不完全确定这个,我之前从未使用LAG。它应该返回上一行值。我在对这个问题的评论中给出了我的解释。快速放置:按日期订单排序,但如果某个人的优先级不是按时间顺序排列,则将其更改为首先反映优先级,方法是将具有更高优先级相同日期戳的旧票证作为较新票证的优先级较低。

编辑:LAG现在使用newdate

SELECT UserName, Subject, Priority, DateStamp
FROM T
INNER JOIN (
    SELECT UserName, DateStamp,
    CASE WHEN LAG(newdate, 1, DateStamp) OVER (Partition BY UserName ORDER BY Priority) > DateStamp 
         THEN LAG(newdate, 1, DateStamp) OVER (Partition By UserName ORDER BY Priority)
         ELSE DateStamp END AS newdate
    FROM T as x ) AS x ON x.UserName = t.UserName
ORDER BY x.newdate, T.Priority

答案 1 :(得分:0)

按照"截止日期"订购。我假设您的每个priorties都有某种形式的SLA与之相关联。将SLA添加到DATESTAMP以确定何时应该到期。按此值排序可确保您的优先级较低的故障单最终会出现在队列中,但仍需要更快地解决优先级较高的故障单。

DECLARE @T TABLE
(
  UserName  VARCHAR(10),
  Subject   VARCHAR(10),
  Priority  INT,
  DateStamp DATETIME
)
;

INSERT INTO @T (UserName,
                Subject,
                Priority,
                DateStamp
               )
VALUES ('THOMAS', 'Error A', 1, '20171120 08:01'),
('THOMAS', 'Error C', 2, '20171120 10:30'),
('THOMAS', 'Error B', 3, '20171120 14:55'),
('HENRY', 'Error B', 1, '20171120 11:14'),
('HENRY', 'Error A', 2, '20171120 18:44'),
('HENRY', 'Error C', 3, '20171120 16:26')
;

SELECT      UserName,
            Subject,
            Priority,
            DateStamp,
            DueDate = CASE Priority
                        WHEN 1
                          THEN DATEADD( HOUR, 2, DateStamp )
                        WHEN 2
                          THEN DATEADD( HOUR, 12, DateStamp )
                        WHEN 3
                          THEN DATEADD( HOUR, 24, DateStamp )
                        ELSE DATEADD( HOUR, 72, DateStamp )
                      END
  FROM      @T
  ORDER BY  DueDate

这也使您很容易看到SLA阈值的影响。

UserName   Subject    Priority    DateStamp               DueDate
---------- ---------- ----------- ----------------------- -----------------------
THOMAS     Error A    1           2017-11-20 08:01:00.000 2017-11-20 10:01:00.000
HENRY      Error B    1           2017-11-20 11:14:00.000 2017-11-20 13:14:00.000
THOMAS     Error C    2           2017-11-20 10:30:00.000 2017-11-20 22:30:00.000
HENRY      Error A    2           2017-11-20 18:44:00.000 2017-11-21 06:44:00.000
THOMAS     Error B    3           2017-11-20 14:55:00.000 2017-11-21 14:55:00.000
HENRY      Error C    3           2017-11-20 16:26:00.000 2017-11-21 16:26:00.000

已更新

我添加了一些额外的记录,并包含一些优先级为4的值,以便更好地展示它们的分发方式。

UserName   Subject    Priority    DateStamp               DueDate
---------- ---------- ----------- ----------------------- -----------------------
HENRY      Error A    2           2017-11-19 19:44:00.000 2017-11-20 07:44:00.000
THOMAS     Error A    1           2017-11-20 08:01:00.000 2017-11-20 10:01:00.000
HENRY      Error B    1           2017-11-20 11:14:00.000 2017-11-20 13:14:00.000
THOMAS     Error C    2           2017-11-20 10:30:00.000 2017-11-20 22:30:00.000
HENRY      Error D    2           2017-11-20 12:44:00.000 2017-11-21 00:44:00.000
THOMAS     Error B    3           2017-11-20 14:55:00.000 2017-11-21 14:55:00.000
HENRY      Error C    3           2017-11-20 16:26:00.000 2017-11-21 16:26:00.000
HENRY      Error F    4           2017-11-18 18:44:00.000 2017-11-21 18:44:00.000
HENRY      Error C    2           2017-11-21 08:44:00.000 2017-11-21 20:44:00.000
HENRY      Error B    2           2017-11-21 18:44:00.000 2017-11-22 06:44:00.000
HENRY      Error E    4           2017-11-19 18:44:00.000 2017-11-22 18:44:00.000

答案 2 :(得分:0)

这里的问题是,如上所述,您的排序标准会导致非传递的比较运算符。考虑:

Thomas | Priority 1 | 10:00
Thomas | Priority 2 | 08:00
Henry  | Priority 1 | 09:00

现在,您想要Thomas Priority 1> Thomas Priority 2,还有Thomas Priority 2>由于时间戳,亨利优先级1和亨利优先级1>托马斯优先级1因为时间戳,所以你有A> B> C>甲

这意味着该套票没有总排序,因此您无法对它们进行有意义的排序。数学https://en.wikipedia.org/wiki/Total_order