SQL,Order By - 如何赋予其他列更高的排序权重?

3

我有这个SQL语句:

SELECT * FROM converts 
WHERE email='myemail@googlemail.com' AND status!='1' 
ORDER BY date ASC, priority DESC

这个SQL语句只按照日期排序,但我想让我的“优先级”列更具权威性。我该怎么做?

它应该首先按照日期排序,但如果两条记录之间的时间为10分钟,则我希望优先级起作用。我该如何在我的SQL语句中实现这一点,还是必须在我的应用程序逻辑中实现?我希望能够在我的SQL语句中完成它。

谢谢大家的帮助。


我认为需求定义不够明确。请考虑以下事项:a) 0:0 1 b) 0:7 2 c) 0:14 3从需求中可以得出:b) 应该在 a) 之前,c) 应该在 b) 之前, 但是 a) 应该在 c) 之前。这与通常的“之前”定义不符。 - Jens Schauder
5个回答

5
您可以将“日期”排序量化为10分钟块,因此如何按floor(unix_timestamp(date)/600)排序,然后按优先级排序。
SELECT * FROM converts 
WHERE email='myemail@googlemail.com' AND status!='1' 
ORDER BY floor(unix_timestamp(date)/600) ASC, priority DESC

尽管两个日期可能仍然相差不到10分钟,但跨越了两个不同的10分钟“块”。也许这已经足够了,但我认为要做到完全符合您的要求最好由应用程序完成。
(OP要求扩展说明....)
取两个时间,它们跨越了十分钟的边界,比如今天的9:09和9:11:
floor(unix_timestamp('2009-03-16 09:09:00')/600) = 2061990 floor(unix_timestamp('2009-03-16 09:11:00')/600) = 2061991
假设您有一个优先级更高的行对于09:11而不是09:09 - 它仍然会出现在09:09行之后,因为它落入了下一个10分钟块,即使只相差2分钟。
因此,这种方法是一种近似,但不能解决最初提出的问题。
按照您陈述问题的方式,如果存在低于10分钟间隔的连续的较低优先级行,则具有高优先级的行可能会在几个小时(或几天、几个月)之前出现。

哇,你太棒了!我刚刚执行了那个查询,输出结果正是我需要的!我还检查了几个日期是否在10分钟内,并且优先级列正确地起作用了。请问Paul,你能解释一下为什么你认为它不够好吗? :) - Abs
我已经扩展了答案以解释。 - Paul Dixon

1

另一种变化可能是:

SELECT * FROM converts 
WHERE email='myemail@googlemail.com' AND status!='1' 
ORDER BY (unix_timestamp(date)/60) - priority 

虽然不完全符合您的要求,但已经非常接近了。


0
如果您正在使用 SQL Server 2005 / 2008,则可以使用递归CTE完成此任务。 请注意,我是在记事本中编写此文本的,并且尚未进行测试。一旦我有机会测试查询结果,我将根据错误更新CTE或完全删除此注释。

DATE_CTE为

AS

(SELECT *
    , 'sequential_order' = ROW_NUMBER() OVER
        (PARTITION BY email
        ORDER BY date ASC, priority DESC)
FROM converts
WHERE email = 'myemail@googlemail.com'
AND status <> '1')

递归日期CTE

作为

(SELECT dc1.*
    , 'sort_level' = 1
FROM date_cte dc1
WHERE sequential_order = 1
UNION
SELECT dc1.*
    , 'sort_level' = CASE
        WHEN DATEDIFF(MINUTE, dc1.date, dc2.date) <= 10 THEN sort_level
        ELSE sort_level + 1 END
LEFT JOIN date_cte dc2
    ON dc1.sequential_order = dc2.sequential_order - 1
WHERE dc1.sequential_order > 1)

SELECT *

FROM recursive_date_cte

ORDER BY sort_level ASC

从recursive_date_cte中选择*

按sort_level升序排序

, priority DESC

0
假设你真的是指“两条记录之间的时间不超过10分钟,然后我希望优先权发挥作用?”
然后按十分钟块排序,然后按优先级排序...
选择... 按 DateDiff(min, 0, Date) / 10 排序,按优先级排序
你可以调整0的值来控制每个“十分钟块”的开始和结束位置... 如果MySQL没有DateDiff函数,请使用在MySQL中提供自某个参考时间以来的分钟数的任何表达式...

-1

只需在ORDER语句中更改列的顺序即可。

SELECT * FROM converts WHERE email='myemail@googlemail.com' AND status!='1' ORDER BY priority DESC, date ASC

日期必须始终在优先级之前,但当某些日期在10分钟内接近时,优先级只需要更高的权威性 :) - Abs
回答者似乎不理解问题。然而,我绝对喜欢回答者的Wall-e图片。 :P - Registered User
是的,那就是我的问题。在我回复之后,我更加注意到问题的本质。不过有时候有些问题非常明显,以至于我认为这是其中之一。 - Gabriel Sosa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接