1

When I am executing

SELECT * FROM TABLE_NAME WHERE ROWNUM <= 20 
MINUS 
SELECT * FROM TABLE_NAME WHERE ROWNUM <= 10 

I get expected result of SKIP 10 TAKE 10 (ten rows)

but if I specify columns explicitly

SELECT COL1, COL2, COL3 FROM TABLE_NAME WHERE ROWNUM <= 20 
MINUS 
SELECT COL1, COL2, COL3 FROM TABLE_NAME WHERE ROWNUM <= 10

I get single record back. (one row)

Why does this happen? How can I fix this?

4

2 回答 2

1

集合操作 UNION、INTERSECT、MINUS 总是删除重复项。(UNION 的表亲 UNION ALL 没有)。

使用 MINUS 时无法避免删除重复项。如果您只关心前三列(并且希望保留重复项),则需要先应用 MINUS 操作,然后才能选择三列。

像这样:

SELECT COL1, COL2, COL3 FROM (
    SELECT * FROM TABLE_NAME WHERE ROWNUM <= 20 
    MINUS 
    SELECT * FROM TABLE_NAME WHERE ROWNUM <= 10
);

进一步思考(由 Gordon 的观察提示) - 虽然我认为这会起作用(对于 MINUS 的两个操作数,ROWNUM 将是相同的),但根本不清楚为什么首先需要 MINUS,无论是在原始查询中使用select *或在我的解决方案中。

在所有情况下,更好的解决方案是只选择一次并使用正确的 WHERE 子句:

WHERE ROWNUM BETWEEN 11 AND 20

我因为没有立即考虑而感到愚蠢...... :-)

于 2016-06-30T15:11:39.107 回答
1

您正在使用没有where rownum < XX order by将在子查询中)。

因此,返回的行可以是表中的任何 10 或 20 行。事实上,当您多次运行查询时,您可能会得到不同的结果。当您在并行系统上运行查询时,这一点尤其明显——无论哪个线程碰巧获取数据,都可能首先返回它(尽管这对于简单的表扫描来说并不那么明显)。

你需要这样的东西:

(SELECT * FROM (SELECT * FROM TABLE_NAME ORDER BY COL1, COL2, COL3) WHERE ROWNUM <= 20)
MINUS 
(SELECT * FROM (SELECT * FROM TABLE_NAME ORDER BY COL1, COL2, COL3) WHERE ROWNUM <= 10) ;
于 2016-06-30T15:01:22.980 回答