我的要求是找出一个月内所有经过的天数。以下是我的示例查询。
CREATE TABLE custom.date_full (
sno NUMBER,
curr_date DATE);
INSERT INTO custom.date_full VALUES ( 1,'27-sep-2018' );
INSERT INTO custom.date_full VALUES ( 2,'27-sep-2018' );
--Query:1 - RETURNS 4 RECORDS AS EXPECTED
SELECT curr_date,
TRUNC (curr_date, 'MM') + LEVEL - 1 AS DAY,
LEVEL
FROM (SELECT * FROM custom.date_full WHERE sno=1)
CONNECT BY level<=4
ORDER BY DAY;
--Query 2: RETURNS 15 RECORDS WITH DUPLICATES
SELECT curr_date,
TRUNC (curr_date, 'MM') + LEVEL - 1 AS DAY,
LEVEL
FROM custom.date_full
WHERE sno=1
CONNECT BY level<=4
ORDER BY DAY;
我的
Query 1
运行良好,但 Query 2
显示重复记录。为什么? 最佳答案
您不了解 CONNECT BY
的工作原理。以下是 Oracle 如何评估您的第二个查询的演练。
如果没有 START WITH
子句,表中的每一行都将用作起点或层次结构中的“根”。
由于您没有 CONNECT BY
条件(如“columnA = PRIOR columnB”),表中的每一行都将被视为每隔一行的子行。这将永远发生,直到达到您的 LEVEL <=4
条件。
所以,
LEVEL 1
--------
SNO 1
SNO 2
说明:表中的每一行都是其自身层次结构的起点(因为您没有
START WITH
条件)。LEVEL 2
--------
SNO 1 -> SNO 1
SNO 1 -> SNO 2
SNO 2 -> SNO 1
SNO 2 -> SNO 2
对这 4 行的解释——SNO 1 和 SNO 2 都是根,对于每个根,SNO 1 和 SNO 2 都是子级。因此,2x2 行 = 4 行。
LEVEL 3
-------
SNO 1 -> SNO 1 -> SNO 1
SNO 1 -> SNO 1 -> SNO 2
SNO 1 -> SNO 2 -> SNO 1
SNO 1 -> SNO 2 -> SNO 2
SNO 2 -> SNO 1 -> SNO 1
SNO 2 -> SNO 1 -> SNO 2
SNO 2 -> SNO 2 -> SNO 1
SNO 2 -> SNO 2 -> SNO 2
对那 8 行的解释。从第 2 级的 4 行开始,SNO 1 和 SNO 2 都是每个的子级,在第 3 级给出 4x2 = 8 行。
级别 4,我不会画出来,同样会给出 8x2 = 16 行。
因此,总共有 2 + 4 + 8 + 16 = 30 行。 (即级别 1 + 级别 2 + 级别 3 + 级别 4)。
然后,在您的
CONNECT BY
处理(如上所示)之后,应用 WHERE
子句,将您的最终结果限制为值(在层次结构的最低级别)为 SNO = 1
的行。这正好是 30 行或 15 行的一半,这就是您得到的。关于sql - 为什么我的层次结构查询显示重复记录?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52950407/