在Oracle SQL中使用UNION操作符时如何排序.我使用两个选择语句和UNION操作符,我想对两个查询的结果进行排



我正在尝试解决HackerRank SQL -PADS问题。

问题是:

生成以下两个结果集:

  1. 查询occupation中所有名字的按字母顺序排列的列表,紧接每个职业的第一个字母作为括号(即:用圆括号括起来)。例如:AnActorName(A),ADoctorName(D),AProfessorName(P),ASingerName(S)

  2. 查询OCCUPATIONS中每个职业的出现次数。按升序排序,并以以下格式输出它们:

    There are a total of [occupation_count] [occupation]s.
    

    其中[occupation_count]OCCUPATIONS中某个职业出现的次数[occupation]小写职业名称。如果有多个Occupation具有相同的[occupation_count],则应按字母顺序排列。

我的解决方案是:

SELECT NAME || '(' || SUBSTR(OCCUPATION,1,1) || ')' 
FROM OCCUPATIONS
ORDER BY NAME 
UNION  
SELECT 'There are a total of ' || COUNT(OCCUPATION) || ' ' ||  LOWER(OCCUPATION) || 's.' 
FROM OCCUPATIONS 
GROUP BY OCCUPATION 
ORDER BY OCCUPATION;
OP:
ERROR at line 4:
ORA-00933: SQL command not properly ended
(It seems, we cannot use ORDER BY BEFORE UNION)

我修改了我的代码:

SELECT NAME || '(' || SUBSTR(OCCUPATION,1,1) || ')' 
FROM OCCUPATIONS 
UNION  
SELECT 'There are a total of ' || COUNT(OCCUPATION) || ' ' ||  LOWER(OCCUPATION) || 's.' 
FROM OCCUPATIONS 
GROUP BY OCCUPATION 
ORDER BY NAME, OCCUPATION;
OP:
ERROR at line 7:
ORA-00904: "NAME": invalid identifier

请帮我一下。

生成以下两个结果集

You areNOT生成两个结果集。您正在执行两个SELECTs,并试图使用UNION将它们合并为单个结果集,这不是问题所要求的。停止使用UNION,使用两个查询

第一个结果集是:

SELECT NAME || '(' || SUBSTR(OCCUPATION,1,1) || ')' 
FROM   OCCUPATIONS 
ORDER BY NAME;

第二个结果集将是:

SELECT 'There are a total of ' || COUNT(OCCUPATION) || ' ' || LOWER(OCCUPATION) || 's.' 
FROM OCCUPATIONS 
GROUP BY OCCUPATION

然后需要ORDER BYand的出现次数然后是职业名称(我留给你来解决)。

因为你想要在一个查询中输出两个有序的数据集,最简单的方法是为每个查询分配一个标识符,然后按该标识符和你想要排序的列排序,例如:

SELECT info
FROM   (SELECT 1 qry, NAME || '(' || SUBSTR(OCCUPATION,1,1) || ')' info
FROM   OCCUPATIONS
UNION ALL
SELECT 2 qry, 'There are a total of ' || COUNT(OCCUPATION) || ' ' ||  LOWER(OCCUPATION) || 's.' info
FROM OCCUPATIONS
GROUP BY OCCUPATION)
ORDER BY qry, info;

请注意,因为这两个查询不会返回相同的行,所以我使用了UNION ALL,因为UNION对结果数据集执行DISTINCT,而UNION ALL不会。此外,我假设如果您有两个具有相同姓名和职业的不同的人(例如,不同的出生日期),您应该输出两行,而不是一行?

还请注意,当您有UNION/UNION ALL查询时,输出列继承第一个查询的列名,这就是为什么第二个查询给您无效标识符错误(您没有为您的列指定别名!)。

请在此尝试,希望有所帮助:

select name||'('||SUBSTR(OCCUPATION,1,1)||')' as col
from OCCUPATIONS
UNION ALL
select 
'There are a total of '||count(occupation)||' '||LOWER(occupation)||'s.' as col
from OCCUPATIONS
group by occupation
order by col
;

如果我们需要调整性能,我们也知道2的选择是不重复的,只需使用UNION ALL.

最新更新