单独放置 WHERE 语句以使 UNION 函数起作用

Placing a WHERE statement separately for a UNION function to work

我正在做一个 hackerrank 练习,我必须找到名字最短和最长的城市,如果有很多名字中的字符数量相同,则按字母顺序取第一个

这是提供的table

经过多次尝试,我成功地创建了这段有效的代码

SELECT * FROM (
SELECT CITY, LENGTH(CITY) AS LENGTH_CITY FROM STATION ORDER BY LENGTH_CITY ASC, CITY) WHERE ROWNUM = 1
UNION
SELECT * FROM (
SELECT CITY, LENGTH(CITY) AS LENGTH_CITY FROM STATION ORDER BY LENGTH_CITY DESC, CITY) WHERE ROWNUM = 1;

所以我的问题是,最初我编写的另一段代码不起作用,我想知道为什么我必须将“WHERE ROWNUM = 1”单独放在 SELECT*让 UNION 工作?

SELECT CITY, LENGTH(CITY) AS LENGTH_CITY FROM STATION WHERE ROWNUM = 1 ORDER BY LENGTH_CITY ASC, CITY
UNION
SELECT CITY, LENGTH(CITY) AS LENGTH_CITY FROM STATION WHERE ROWNUM = 1 ORDER BY LENGTH_CITY DESC, CITY;

我会推荐 row_number() 而不是 rownum。使用它,你不需要union,你可以这样做:

select *
from (
    select s.*, 
        row_number() over(order by length(city), city) rn_asc,
        row_number() over(order by length(city) desc, city) rn_desc
    from station s
) s
where 1 in (rn_asc, rn_desc)

如果您使用 union 执行此操作(效率低于上述解决方案),则 row-limiting 子句更合适(从 Oracle 12c 开始可用):

(
    select * 
    from station 
    order by length(city), city 
    fetch first 1 row only
) union all (
    select * 
    from station 
    order by length(city) desc, city 
    fetch first row only
)

I was wondering why do I have to place the "WHERE ROWNUM = 1" separately in a SELECT* for the UNION to work?

UNION无关,与ORDER BY有关。

您发布的第二个查询肯定没有按照您的预期执行,因为 WHERE 子句在 ORDER BY 之前执行,因此:

select city
from station
where rownum = 1
order by city

说:给我 table 中的第一个 随机 行,然后按 city.

对该行进行排序

因此:首先对行进行排序,然后取第一个:

select *
from (select city
      from station
      order by city
     )
where rownum = 1

将其应用于您的情况,长度 等等。