有没有办法在 SQL 中加入两个查询,每个查询都有一个 order by?

Posted

技术标签:

【中文标题】有没有办法在 SQL 中加入两个查询,每个查询都有一个 order by?【英文标题】:Is there a way to join two queries in SQL each with an order by? 【发布时间】:2021-08-19 05:44:44 【问题描述】:

我有两个查询从两个表中返回数据:

SELECT TOP 3 
    AE.id, AE.name, COUNT(R.id) 'number of reserves'
FROM 
    AIRPORT AE
INNER JOIN 
    FLY V ON V.id_destiny = AE.id
INNER JOIN 
    RESERVE R ON R.id_fly = V.id
GROUP BY 
    AE.id, AE.name
ORDER BY 
    COUNT(R.id) DESC;

返回数据示例:

id name number of reserves
6 name1 27
4 name2 18
14 name3 14

SELECT TOP 3 
    AE.id, AE.name, COUNT(R.id) 'number of reserves'
FROM 
    AEROPUERTO AE
LEFT JOIN 
    FLY V ON V.id_destiny = AE.id
LEFT JOIN 
    RESERVE R ON R.id_fly = V.id
GROUP BY 
    AE.id, AE.name
ORDER BY 
    COUNT(R.id) ASC;

第二个查询返回的数据示例:

id name number of reserves
7 name4 0
11 name5 0
12 name6 0

我需要将它们组合成一个输出,首先是第一个查询(以相同的顺序),然​​后是第二个查询,顺序相同,如下所示:

id name number of reserves
6 name1 27
4 name2 18
14 name3 14
7 name4 0
11 name5 0
12 name6 0

有办法吗?

编辑:我已经尝试过union all 选项,但我不能在每个查询中使用group by,因此返回的表与我需要的不同

(SELECT TOP 3 AE.id, AE.name, COUNT(R.id) 'number of reserves'
FROM AIRPORT AE
    INNER JOIN FLY V
ON V.id_destiny = AE.id
    INNER JOIN RESERVE R
ON R.id_fly = V.id
GROUP BY AE.id, AE.name)
UNION ALL
(SELECT TOP 3 AE.id, AE.name, COUNT(R.id) 'number of reserves'
FROM AEROPUERTO AE
    LEFT JOIN FLY V
ON V.id_destiny= AE.id
    LEFT JOIN RESERVE R
ON R.id_fly = V.id
GROUP BY AE.id, AE.name)
ORDER BY COUNT(R.id) ASC;

【问题讨论】:

使用UNION ALL 您需要:1) 将每个查询括在括号中,2) 使用 UNION ALL 将它们合并为一个,3) 添加 ORDER BY 以指定合并结果集的顺序。 已经尝试过了,但没有成功,因为如果 group by 存在,它会发送错误。 union all 使用人工列标识源,然后按该列排序并计算计数 【参考方案1】:

当您将每个查询括在括号中时,它就像一个派生表。您将需要一个SELECT 子句来从派生表中进行选择。

SELECT *
FROM
(
    -- Your first query here
) AS Q1

UNION ALL

SELECT *
FROM
(
    -- Your second query here
) AS Q2

你也可以使用CTE来做

WITH 
Q1 AS
(
    -- Your first query here
),
Q2 AS
(
    -- Your second query here
)
SELECT *
FROM   Q1
UNION ALL
SELECT *
FROm   Q2

编辑:如果您还希望两个查询中的最终结果具有相同的顺序,请为最终查询添加另一列ORDER BY

WITH 
Q1 AS
(
    SELECT TOP 3 
           AE.id, AE.name, COUNT(R.id) 'number of reserves',
           Q  = 1,
           RN = ROW_NUMBER() OVER (ORDER BY COUNT(R.id) DESC)
    FROM 
           AIRPORT AE
    INNER JOIN 
           FLY V ON V.id_destiny = AE.id
    INNER JOIN 
           RESERVE R ON R.id_fly = V.id
    GROUP BY 
           AE.id, AE.name
    ORDER BY 
           COUNT(R.id) DESC
),
Q2 AS
(
    SELECT TOP 3 
           AE.id, AE.name, COUNT(R.id) 'number of reserves',
           Q  = 2,
           RN = ROW_NUMBER() OVER (ORDER BY COUNT(R.id) DESC)
    FROM 
           AEROPUERTO AE
    LEFT JOIN 
           FLY V ON V.id_destiny = AE.id
    LEFT JOIN 
           RESERVE R ON R.id_fly = V.id
    GROUP BY 
           AE.id, AE.name
    ORDER BY 
           COUNT(R.id) ASC
)
SELECT *
FROM   Q1
UNION ALL
SELECT *
FROM   Q2
ORDER BY Q, RN

【讨论】:

这并没有解释如何明确按照 OP 的规定对结果进行排序。无法保证union all 会产生预期的结果。 我认为 OP 只需要每个查询中的 ORDER BY。无论如何,我已经编辑了答案并使用另一个查询进行了更新。【参考方案2】:

我打破了查询并制作了两个临时表。您也可以在 CTE(Commn Table 表达式)中执行此操作。

 SELECT TOP 3 AE.id, AE.name, COUNT(R.id) 'number of reserves'
 INTO #Temp_1
 FROM AIRPORT AE
    INNER JOIN FLY V
       ON V.id_destiny = AE.id
    INNER JOIN RESERVE R
      ON R.id_fly = V.id
  GROUP BY AE.id, AE.name


 SELECT TOP 3 AE.id, AE.name, COUNT(R.id) 'number of reserves'
 into #Temp_2
 FROM AEROPUERTO AE
    LEFT JOIN FLY V
      ON V.id_destiny= AE.id
    LEFT JOIN RESERVE R
      ON R.id_fly = V.id
  GROUP BY AE.id, AE.nam

  SELECT *
  FROM #Temp_1
  UNION ALL
 SELECT * 
  FROM #Temp_2

 drop table #Temp_1
  drop table #Temp_2

【讨论】:

以上是关于有没有办法在 SQL 中加入两个查询,每个查询都有一个 order by?的主要内容,如果未能解决你的问题,请参考以下文章

在 MySQL 中加入“博客”表和“评论”表

在 EntityFramework 中加入两个 M:N 关系

如何在sql的查询结果中加入序号

如何在查询中加入 MS-SQL 和 MySQL 表?

有没有办法限制在 spark sql 中加入表时读取的数据?

在 oracle sql developer 中加入查询快,在 odp.net 中超慢