【问题标题】:How to combine two SQL queries with different ORDER BY clauses如何将两个具有不同 ORDER BY 子句的 SQL 查询组合起来
【发布时间】:2015-01-13 20:51:05
【问题描述】:

我在网上查找,但只能找到两个查询与 相同 order by 结合。

第一个查询:

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

第二次查询:

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

我需要将第一个查询和第二个查询合并为一个,执行第一个查询,然后执行第二个查询给我一个完整的列表。

【问题讨论】:

  • date,Priority DESC 订购
  • @iamde_coder:除此之外,这可能是为了阅读ORDER BY priority DESC, date:这会将BY date(特定于第二个查询)也应用于第一个查询的结果。随着 OP 明确指出不同的排序标准,无论出于何种原因,这可能无法提供所要求的内容。它是否真的有所作为,当然取决于真实数据。

标签: php mysql sql select sql-order-by


【解决方案1】:

不只是 1 个查询吗...优先级是 > 或 = 0

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

【讨论】:

    【解决方案2】:

    您可以使用union all 运算符。不幸的是,union [all] 不允许将order by 子句应用于每个查询,因此需要一些技巧。例如,您可以在子查询中“隐藏”order by 子句:

    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
    

    【讨论】:

    • 请注意,MySQL 不保证外部查询返回行的顺序;我们观察到一致的行为,但这不是保证。 MySQL 确实允许使用隐式 UNION ALL 操作的 ORDER BY,例如(SELECT ... ) UNION ALL (SELECT ... ) ORDER BY 2 DESC, 1。但是为什么在这种情况下使用两个查询,因为我们保证没有重叠。
    【解决方案3】:

    虽然将priority > 0priority = 0 组合成priority >= 0 似乎是公平的,但第二个查询的排序顺序必须 - 严格来说- 应用于第一个检索到的数据。由于没有关于实际数据的详细信息,很难判断它是否有所作为。但是,如果有疑问(正如 OP 明确指出的那样),我会选择

    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
    ;
    

    我用一些假数据对@Spock 的结果进行了测试,实际上得到了不同的结果:
    SQL Fiddle

    2015-08-08 更新

    为了在更广泛的范围内解决一般问题,让我们假设一些WHERE 条件,它们不容易组合成一个条件:

    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
    ;
    

    这可以解决:

    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
    ;
    

    所以我们引入了resultSet 来处理它们中的每一个,并指定特定的排序标准。

    查看实际操作:SQL Fiddle
    如果需要调整/进一步详细信息,请发表评论。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多