我的要求是找出一个月内所有经过的天数。以下是我的示例查询。

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 都是根,对于每个根,SN​​O 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/

10-11 07:49