基于多个WHERE案例的ORDER BY,这可能吗?

时间:2019-04-01 19:58:36

标签: mysql sql

事件可以是1天的事件,也可以是正在进行的事件。这意味着有时事件可能会持续数天,数周或数月。

现在,可以按END(升序显示)或ASC中的START(基于开始日期的事件)的升序对查询结果进行排序。但是,在这两种情况下,我都有自己的局限性,我试图尽量减少这种情况。

按END排序时,有时正在进行的事件和已经开始的事件会被推送到列表的后面。

按START排序时,已经开始且正在进行的事件最终会占据列表的第一部分。

是否可以基于逻辑而不是列链接多个ORDER BY语句?

例如:

获取在接下来的7天内到期的事件:

SELECT * FROM data WHERE end < NOW() + INTERVAL 7 DAY;

获取从今天起7天到14天之内仍在进行的事件:

SELECT * FROM data WHERE NOW() + INTERVAL 7 DAY >= start AND end < NOW() + INTERVAL 14 DAY;

获取所有剩余事件...

SELECT * FROM data WHERE end >= NOW() + INTERVAL 14 DAY;

基本上可以将它们合并为一个查询吗?

SELECT * FROM data
ORDER BY (logic 1), (logic 2), (logic 3);

或者,我的确可以通过运行3个独立的查询并在服务器端建立结果数组来使其工作,但是如果可能的话,我想简化我的代码。

希望最终结果将始终显示将首先在7天内到期的事件列表,然后显示在7到14天之间(可能正在开始或正在进行)的事件,然后是仍在进行或开始的事件的列表从今天起14天之后。

3 个答案:

答案 0 :(得分:3)

根据您的SQL数据库,您可以执行以下操作:

SELECT * FROM data 
WHERE (end < NOW() + INTERVAL 7 DAY) -- logic 1
    or (NOW() + INTERVAL 7 DAY >= start AND end < NOW() + INTERVAL 14 DAY) -- logic 2
    or (NOW() + INTERVAL 7 DAY >= start AND end < NOW() + INTERVAL 14 DAY) -- logic 3
order by 
  case 
    when (end < NOW() + INTERVAL 7 DAY) then 1 
    when (NOW() + INTERVAL 7 DAY >= start AND end < NOW() + INTERVAL 14 DAY) then 2
    when (NOW() + INTERVAL 7 DAY >= start AND end < NOW() + INTERVAL 14 DAY) then 3
    else 4
  end asc
;

您也可以使用union all

  SELECT 1 as sort_order, * FROM data 
  WHERE (end < NOW() + INTERVAL 7 DAY)
union all
  SELECT 2 as sort_order, * FROM data 
  WHERE (NOW() + INTERVAL 7 DAY >= start AND end < NOW() + INTERVAL 14 DAY)
union all
  SELECT 3 as sort_order, * FROM data 
  where NOW() + INTERVAL 7 DAY >= start AND end < NOW() + INTERVAL 14 DAY

可能不需要sort_order,但是如果您得到的结果不是select的顺序,则可以使用子查询;数据库也会禁止您在order by中使用union all

   select * 
   from (
      SELECT 1 as sort_order, * FROM data 
      WHERE (end < NOW() + INTERVAL 7 DAY)
    union all
      SELECT 2 as sort_order, * FROM data 
      WHERE (NOW() + INTERVAL 7 DAY >= start AND end < NOW() + INTERVAL 14 DAY)
    union all
      SELECT 3 as sort_order, * FROM data 
      where NOW() + INTERVAL 7 DAY >= start AND end < NOW() + INTERVAL 14 DAY
   ) order by sort_order asc -- and any other key

如果可能的话,我会亲自去找union all(更易读)。

答案 1 :(得分:2)

您可以尝试使用UNION,在其中选择数据集,并在其中具有所需顺序的列。例如

SELECT 1 as orderby,* FROM data WHERE end < NOW() + INTERVAL 7 DAY;
UNION ALL
SELECT 2, * FROM data WHERE NOW() + INTERVAL 7 DAY >= start AND end < NOW() + INTERVAL 14 DAY
UNION ALL
SELECT 3, * FROM data WHERE end >= NOW() + INTERVAL 14 DAY
ORDER BY orderby, end

P.S。我建议您不要在数据库中使用SQL关键字(例如end)作为列名,这有时会引起问题,enddate会是更好的列名。

P.P.S。避免执行SELECT *,最好显式列出所需的列。

答案 2 :(得分:1)

我认为您正在使用MySQL。

在select子句中使用case when .. then .. end,然后按此列排序。

select *, case 
 when end < NOW() + INTERVAL 7 DAY then 1 
 when NOW() + INTERVAL 7 DAY >= start AND end < NOW() + INTERVAL 14 DAY then 2
 else 3 as priority
from data 
order by priority

此外,您可以在order by子句中使用case

注意:我没有处理您的业务逻辑,因此请对其进行良好的测试,只是向您提供如何实现它,希望对您有所帮助。

相关问题