有没有办法在 UNION 之后得到第一行?
There is a way to get the first row after UNION?
我正在尝试获取两列中重复次数最多的值,此查询 运行 正常,我得到了预期的结果。但我只想要第一行,可以用 ROWNUM =1 得到吗?或者类似的东西?
我的环境是 Oracle 11 和 SQL 开发人员。
我的代码:
SELECT AIR_ARB, COUNT(*) FROM
(
SELECT AIR_ARB FROM AIR_INFO WHERE V_VX IN (910208,910209,9......) AND V_Y IN
(826369,826370,8.....)
UNION ALL
SELECT AIR_MAT FROM AIR_INFO WHERE V_VX IN (910208,910209,9......) AND V_Y IN
(826369,826370,8.....)
) t
GROUP BY AIR_ARB
ORDER BY COUNT (*) desc
我的结果:
AIR_ARB COUNT(*)
null 64
100 23
0 20
72 15
143 3
43 3
您需要一个额外的子查询:
SELECT a.*
FROM (SELECT AIR_ARB, COUNT(*) as cnt
FROM (SELECT AIR_ARB FROM AIR_INFO WHERE V_VX IN (910208,910209,9......) AND V_Y IN (826369,826370,8.....)
UNION ALL
SELECT AIR_MAT FROM AIR_INFO WHERE V_VX IN (910208,910209,9......) AND V_Y IN(826369,826370,8.....)
) t
GROUP BY AIR_ARB
ORDER BY COUNT (*) desc
) a
WHERE rownum = 1;
您还可以使用百分比来限制结果,如下所示,在 "ORDER BY"
之后添加以下表达式
FETCH FIRST 0.01 PERCENT ROWS ONLY
如果您的 IN
列表相同,那么您可以使用 UNPIVOT
然后 GROUP BY
和 ORDER BY
然后在排序后按 WHERE ROWNUM = 1
过滤。
这意味着您只需要编写一次列表(使查询更易于调试和维护)并且 Oracle 只需要扫描 AIR_INFO
table/index 一次(而 UNION
可以使用两次扫描)。
SELECT *
FROM (
SELECT value AS air_arb,
COUNT(*)
FROM AIR_INFO
UNPIVOT ( value FOR type IN ( AIR_ARB, AIR_MAT ) )
WHERE V_VX IN (910208,910209)
AND V_Y IN (826369,826370)
GROUP BY value
ORDER BY COUNT(*) DESC
)
WHERE rownum = 1;
所以对于测试数据:
CREATE TABLE air_info ( v_vx, v_y, air_arb, air_mat ) AS
SELECT 910208, 826369, 1, 2 FROM DUAL UNION ALL
SELECT 910209, 826370, 3, 2 FROM DUAL;
这输出:
AIR_ARB | COUNT(*)
------: | -------:
2 | 2
db<>fiddle here
我正在尝试获取两列中重复次数最多的值,此查询 运行 正常,我得到了预期的结果。但我只想要第一行,可以用 ROWNUM =1 得到吗?或者类似的东西?
我的环境是 Oracle 11 和 SQL 开发人员。
我的代码:
SELECT AIR_ARB, COUNT(*) FROM
(
SELECT AIR_ARB FROM AIR_INFO WHERE V_VX IN (910208,910209,9......) AND V_Y IN
(826369,826370,8.....)
UNION ALL
SELECT AIR_MAT FROM AIR_INFO WHERE V_VX IN (910208,910209,9......) AND V_Y IN
(826369,826370,8.....)
) t
GROUP BY AIR_ARB
ORDER BY COUNT (*) desc
我的结果:
AIR_ARB COUNT(*)
null 64
100 23
0 20
72 15
143 3
43 3
您需要一个额外的子查询:
SELECT a.*
FROM (SELECT AIR_ARB, COUNT(*) as cnt
FROM (SELECT AIR_ARB FROM AIR_INFO WHERE V_VX IN (910208,910209,9......) AND V_Y IN (826369,826370,8.....)
UNION ALL
SELECT AIR_MAT FROM AIR_INFO WHERE V_VX IN (910208,910209,9......) AND V_Y IN(826369,826370,8.....)
) t
GROUP BY AIR_ARB
ORDER BY COUNT (*) desc
) a
WHERE rownum = 1;
您还可以使用百分比来限制结果,如下所示,在 "ORDER BY"
之后添加以下表达式 FETCH FIRST 0.01 PERCENT ROWS ONLY
如果您的 IN
列表相同,那么您可以使用 UNPIVOT
然后 GROUP BY
和 ORDER BY
然后在排序后按 WHERE ROWNUM = 1
过滤。
这意味着您只需要编写一次列表(使查询更易于调试和维护)并且 Oracle 只需要扫描 AIR_INFO
table/index 一次(而 UNION
可以使用两次扫描)。
SELECT *
FROM (
SELECT value AS air_arb,
COUNT(*)
FROM AIR_INFO
UNPIVOT ( value FOR type IN ( AIR_ARB, AIR_MAT ) )
WHERE V_VX IN (910208,910209)
AND V_Y IN (826369,826370)
GROUP BY value
ORDER BY COUNT(*) DESC
)
WHERE rownum = 1;
所以对于测试数据:
CREATE TABLE air_info ( v_vx, v_y, air_arb, air_mat ) AS
SELECT 910208, 826369, 1, 2 FROM DUAL UNION ALL
SELECT 910209, 826370, 3, 2 FROM DUAL;
这输出:
AIR_ARB | COUNT(*) ------: | -------: 2 | 2
db<>fiddle here