内部联接和 row_number

问题描述 投票:0回答:1

我在 Oracle DB 上有以下 SQL。我想在状态变为“坏”之前获取名称和 ID。以 4/9/2023 凯尔为例。该文件由 kyle 批准,我不同意,然后发回给 Kyle。

任何帮助将不胜感激,谢谢。

WITH HISTORY AS 
(
    SELECT 
        ROW_NUMBER() OVER (PARTITION BY MY_TABLE.D_NO ORDER BY MY_TABLE.DATE) RN,
        MY_TABLE.*
    FROM 
        MY_TABLE
    WHERE 
        MY_TABLE.DATE IS NOT NULL
)
SELECT 
    ALL_CUSTOMERS.D_NO,
    HISTORY.*
FROM 
    ALL_CUSTOMERS
INNER JOIN 
    HISTORY ON HISTORY.D_NO = ALL_CUSTOMERS.D_NO
            AND HISTORY.STATUS = 'BAD'

MY_TABLE
看起来像这样

DEPT    D_NO    DATE         STATUS NAME
AC  DAN 4/9/2023    GOOD    KYLE
BG  DAN 4/5/2023    BAD ME
AC  DAN 4/4/2023    GOOD    KYLE
AB  DAN 4/2/2023    GOOD    LUKE
BC  DAN 3/9/2023    BAD VADER
DG  BEN 4/3/2023    GOOD    VADER
BG  BEN 4/3/2023    GOOD    ME
BC  BEN 4/2/2023    BAD LUKE

ALL_CUSTOMERS 是一个更广泛的表,只有“D_no”列。

我创建了另一个连接并给我留下了 Kyle 部门在它变坏之前发生的所有批准。但是我不知道如何选择最后一个。

INNER JOIN 
    HISTORY HISTORY2 ON HISTORY2.D_NO = ALL_CUSTOMERS.D.NO
                     AND HISTORY.DEPT = HISTORY2.D_NO
                     AND HISTORY.DATE > HISTORY2.DATE
sql inner-join row-number oracle19c
1个回答
0
投票

要在状态变为“坏”之前获取名称和 ID,您可以修改查询以检索具有“坏”状态的每个 D_NO 的“好”状态的最新记录。您可以使用子查询查找每个状态为“GOOD”的 D_NO 的最新记录,然后将其与原始查询结合起来以获取状态变为“坏”之前的名称和 ID。这是一个示例查询:

    WITH HISTORY AS 
(
    SELECT 
        ROW_NUMBER() OVER (PARTITION BY MY_TABLE.D_NO ORDER BY MY_TABLE.DATE) RN,
        MY_TABLE.*
    FROM 
        MY_TABLE
    WHERE 
        MY_TABLE.DATE IS NOT NULL
)
SELECT 
    ALL_CUSTOMERS.D_NO,
    GOOD_HISTORY.NAME,
    GOOD_HISTORY.ID,
    HISTORY.*
FROM 
    ALL_CUSTOMERS
INNER JOIN 
    HISTORY ON HISTORY.D_NO = ALL_CUSTOMERS.D_NO
            AND HISTORY.STATUS = 'BAD'
INNER JOIN 
    (
        SELECT 
            D_NO,
            NAME,
            ID
        FROM 
            (
                SELECT 
                    ROW_NUMBER() OVER (PARTITION BY D_NO ORDER BY DATE DESC) RN,
                    NAME,
                    ID,
                    STATUS,
                    D_NO
                FROM 
                    MY_TABLE
                WHERE 
                    DATE IS NOT NULL
            )
        WHERE 
            RN = 1 AND STATUS = 'GOOD'
    ) GOOD_HISTORY ON GOOD_HISTORY.D_NO = ALL_CUSTOMERS.D_NO
ORDER BY 
    ALL_CUSTOMERS.D_NO, HISTORY.DATE DESC;
© www.soinside.com 2019 - 2024. All rights reserved.