【问题标题】:SQL, Order By - How to give more authority to other columns?SQL,Order By - 如何赋予其他列更多权限?
【发布时间】:2009-03-15 14:43:28
【问题描述】:

我有这个 SQL 语句:

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

这只是按日期排序,但我想给我的专栏“优先级”更多权限。我怎样才能做到这一点?

它应该首先按日期排序,但如果两条记录之间的时间是 10 分钟,那么我希望优先权接管。如何在我的 SQL 语句中执行此操作,还是必须在我的应用程序逻辑中执行此操作?我希望我可以在我的 SQL 语句中做到这一点。

感谢大家的帮助

【问题讨论】:

  • 我认为要求没有明确定义。考虑以下条目: a) 0:0 1 b) 0:7 2 c) 0:14 3 从要求得出: b) 应该在 a) 之前,c) 在 b) 之前,但是 a) 应该在 c 之前)。这对于“之前”的通常定义是不可能的

标签: mysql sql sql-order-by


【解决方案1】:

您可以将“日期”排序量化为 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 分钟内并且优先级列正确接管。你能解释一下为什么你认为这还不够,请保罗:)
  • 我已经扩展了答案来解释
【解决方案2】:

另一种变化是:

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

仍然不完全符合您的要求,但非常接近。

【讨论】:

    【解决方案3】:

    假设您的真正意思是“两条记录之间的时间为 10 分钟 [或更短],那么我希望优先接管?

    然后只需按十分钟块排序,然后按优先级...

    选择 ...
    按 DateDiff(min, 0, Date) / 10, Priority 排序

    您可以调整 0 值来控制每个“tem-minute-block”开始和停止的位置... 如果 MySql 没有 DateDiff 函数,请使用 MySQL 中提供自某个参考时间以来的分钟数的任何表达式...

    【讨论】:

      【解决方案4】:

      如果您使用的是 SQL Server 2005 / 2008,您可以使用递归 CTE 完成此任务。请注意我在记事本中写了这段文字,还没有经过测试。一旦我有机会测试查询结果,如果有错误,我将更新 CTE 或完全删除此评论。

      与日期_cte

      作为

      (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')
      

      ,recursive_date_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)
      

      选择 *

      FROM recursive_date_cte

      按排序级别 ASC 排序

      , priority DESC
      

      【讨论】:

        【解决方案5】:

        只需更改订单声明中的订单或列

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

        【讨论】:

        • 日期必须始终在优先级之前,但当某些日期在 10 分钟内接近每个日期时,优先级需要更多权限:)
        • 响应者似乎没有理解这个问题。但是,我绝对喜欢 Wall-e 的响应者图片。 :P
        • 是的,那是我的问题,我回复后,我更注意了,发现问题是其他的。无论如何,有时有些问题很明显,我认为这是其中之一
        猜你喜欢
        • 1970-01-01
        • 2015-07-16
        • 1970-01-01
        • 2013-03-15
        • 1970-01-01
        • 2023-03-23
        • 2012-06-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多