有没有办法在 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?的主要内容,如果未能解决你的问题,请参考以下文章
在 EntityFramework 中加入两个 M:N 关系