How to combine two SQL queries with different ORDER BY clauses

﹥>﹥吖頭↗ 提交于 2020-01-21 10:22:17

问题


I looked online, but I could only find two queries combined with the same order by.

First query:

SELECT
  Name
  , Priority
FROM Music
WHERE `Priority` > 0 AND `date` > '2014-10-27 20:04:25'
ORDER BY `Priority` DESC

Second query:

SELECT
  Name
  , Priority
FROM Music
WHERE `Priority` = 0 AND `date` > '2014-10-27 20:04:25'
ORDER BY `date`

I need to combine the first and the second query into one, where the first query is executed and then the second query is executed giving me a complete list.


回答1:


Is it not just 1 query... Where Priority is both > or = 0

select Name, Priority 
from Music 
where `Priority` >= 0 
AND `date` > '2014-10-27 20:04:25' 
order by `Priority` DESC, `date`



回答2:


You could use the union all operator. Unfortunately, union [all] does not allow applying an order by clause to each query, so some trickery is required. For instance, you can "hide" the order by clause inside a subquery:

SELECT *
FROM   (SELECT   Name, Priority 
        FROM     Music 
        WHERE    `Priority` > 0 AND `date` > '2014-10-27 20:04:25' 
        ORDER BY `Priority` DESC) t
UNION ALL
SELECT *
FROM   (SELECT   Name, Priority
        FROM     Music
        WHERE    `Priority` = 0 AND `date` > '2014-10-27 20:04:25'
        ORDER BY `date`) s



回答3:


Whilst combining priority > 0 and priority = 0 into priority >= 0 seems fair, the sort order for the second query must -strictly speaking- not be applied to the data retrieved by the first one. With no detailed information on the actual data, it's hard to tell whether it makes a difference. However, in case of doubt (and as OP does explicitly point out the fact), I'd go for

SELECT
  name
  , priority
FROM MUSIC
WHERE priority >= 0
  AND date > '2014-10-27 20:04:25'
ORDER BY priority DESC, CASE priority WHEN 0 THEN date END
;

I tested against @Spock's result with some fake data, and do actually get a different result:
SQL Fiddle

Update 2015-08-08

To address the general problem at a slightly wider scale, let's suppose some WHERE conditions, which are not as easily combined into a single one:

SELECT
  name
  , priority
  , date
FROM MUSIC
WHERE priority > 1
  AND date > '2014-10-27 20:04:25'
ORDER BY priority DESC, date DESC
;

SELECT
  name
  , priority
  , date
FROM MUSIC
WHERE priority <= 1
  AND date < '2014-10-26 00:00:00'
ORDER BY date
;

This could be addressed along:

SELECT
  name
  , priority
  , date
FROM
  (SELECT
    1 resultSet
    , name
    , priority
    , date
  FROM MUSIC
  WHERE priority > 1
    AND date > '2014-10-27 20:04:25'
  UNION ALL
  SELECT
    2 resultSet
    , name
    , priority
    , date
  FROM MUSIC
  WHERE priority <= 1
    AND date < '2014-10-26 00:00:00'
  ) T
ORDER BY resultSet,
  CASE resultSet
  WHEN 1 THEN priority
  END DESC,
  CASE resultSet
  WHEN 1 THEN date
  END DESC,
  CASE resultSet
  WHEN 2 THEN date
  END
;

So we introduce resultSet to get a handle on each of them, and specify specific sort criteria.

See it in action: SQL Fiddle
Please comment, if and as this requires adjustment / further detail.



来源:https://stackoverflow.com/questions/27931257/how-to-combine-two-sql-queries-with-different-order-by-clauses

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!