这很奇怪,所以我可以用一双备用的眼睛来了解发生了什么。
所以我有这个问题:
WITH x as (
SELECT num_aula, tipo_aula, min(abs(capienza-1)) score
FROM aula
JOIN (
select num_aula, tipo_aula
from aula
where tipo_aula = 'Laboratorio'
minus
select num_aula, tipo_aula
from occr_lezione
where to_char(Data_inizio_occr_lezione,'hh24:mi') = '12:30'
and Nome_sede = 'Centro Direzionale'
and Giorno_lezione = 2
)
USING(num_aula,tipo_aula)
GROUP BY num_aula, tipo_aula
ORDER BY score asc
)
SELECT *
FROM x
返回此结果集:
NUM TIPO_AULA SCORE
--- -------------------- ----------
1 Laboratorio 35
2 Laboratorio 35
这是理想的结果。
现在,如果我将此行添加到查询中:
WHERE rownum = 1;
应该返回表格的第一行,我明白了:
NUM TIPO_AULA SCORE
--- -------------------- ----------
2 Laboratorio 35
这怎么可能?
答案 0 :(得分:2)
我认为您真正想要的查询是
WITH x as (
SELECT num_aula,
tipo_aula, min(abs(capienza-1)) score,
row_number() over(partition by num_aula, tipo_aula order by score asc ) as seq
FROM aula
JOIN (
select num_aula, tipo_aula
from aula
where tipo_aula = 'Laboratorio'
minus
select num_aula, tipo_aula
from occr_lezione
where to_char(Data_inizio_occr_lezione,'hh24:mi') = '12:30'
and Nome_sede = 'Centro Direzionale'
and Giorno_lezione = 2
)
USING(num_aula,tipo_aula)
)
SELECT *
FROM x
WHERE x.seq = 1;
ROWNUM
关键字的行为与您的想法不同,请参阅this article about rownum。
要提供更多详细信息,请在为结果集指定任何订单之前分配ROWNUM
。
如果您确实希望使用ROWNUM
关键字获得正确的结果,那么您可以使用首先排序的子查询来实现此目的,然后将rownum生成到实际排序的结果集。但是,我更喜欢第一种方法,因为在我看来它更具可读性,但你可以自由选择这种方法。
SELECT *
FROM (SELECT num_aula,
tipo_aula, min(abs(capienza-1)) score
FROM aula
JOIN (
select num_aula, tipo_aula
from aula
where tipo_aula = 'Laboratorio'
minus
select num_aula, tipo_aula
from occr_lezione
where to_char(Data_inizio_occr_lezione,'hh24:mi') = '12:30'
and Nome_sede = 'Centro Direzionale'
and Giorno_lezione = 2
) USING(num_aula,tipo_aula)
GROUP BY num_aula, tipo_aula
ORDER BY score asc) x
WHERE x.rownum = 1;
答案 1 :(得分:1)
在进行任何排序之前将rownum分配给该行,因此我怀疑在没有where rownum = 1的情况下删除您的订单并运行将返回:
NUM TIPO_AULA SCORE
--- -------------------- ----------
2 Laboratorio 35
1 Laboratorio 35
有一篇关于rownum的好文章可以在这里找到: http://www.oracle.com/technetwork/issue-archive/2006/06-sep/o56asktom-086197.html
答案 2 :(得分:1)
我不确定这里的问题是rownum
。您使用的是order by score
,但这并不能唯一地定义订单,因为有score
的重复值。
尝试使用order by score, num
以获得稳定的排序,看看是否能解决您的问题。
请注意,缺少稳定排序也会影响row_number()
,因此只需切换到row_number()
可能无法解决问题 - 除非您包含一个加法字段以使排序稳定。
答案 3 :(得分:1)
SELECT num_aula, tipo_aula, min(abs(capienza-1)) score
FROM aula
JOIN (
select num_aula, tipo_aula
from aula
where tipo_aula = 'Laboratorio'
minus
select num_aula, tipo_aula
from occr_lezione
where to_char(Data_inizio_occr_lezione,'hh24:mi') = '12:30'
and Nome_sede = 'Centro Direzionale'
and Giorno_lezione = 2
)
USING(num_aula,tipo_aula)
GROUP BY num_aula, tipo_aula
ORDER BY score asc
FETCH FIRST ROW ONLY;
使用FETCH FIRST ROW ONLY
会对结果进行排序,然后返回第一行,这样您就不需要再次选择并拥有WHERE ROWNUM = 1
。
答案 4 :(得分:-2)
如果你这样说:
with t as
(
select *
from foo
order by foo.x
)
select *
from t
where t.rownum = 1
您尚未在实际查询中通过order by
指定订单。 SQL可以按任意顺序自由返回结果集(甚至可以改变从一个执行到另一个执行的顺序)。
优化器将忽略内部'select'语句中的order by
,除非您在内部选择中使用行编号或分区等执行某些操作。
您假设排序顺序相对于重复值的排序是稳定的。
所以......你需要写这样的东西:
with t as
(
select *
from foo
)
select *
from t
order by foo.x, foo.id
where t.rownum = 1