Если строка из левой объединенной таблицы равна нулю, используйте другую строку - PullRequest
2 голосов
/ 04 августа 2020

У меня есть две таблицы, к которым я пытаюсь присоединиться (см. Ниже). У каждого есть те же четыре столбца, к которым мне нужно присоединиться. Второй - это полный список, в то время как в первом могут отсутствовать некоторые записи.

Если записи отсутствуют, я хочу использовать наименьший ROWNUM, который соответствует трем другим. Я не вижу на этом пути через лес.

    DECLARE @TEMP AS TABLE
        (
            OCC_CODE VARCHAR(2),
            ACCOUNTNO VARCHAR(36),
            IMPNO NUMERIC(14,0),
            TAX_YEAR NUMERIC(4,0),
            ROWNUM NUMERIC(1,0)
        )
    INSERT INTO @TEMP
    VALUES
        ('T1','A1',1,2018,1),
        ('T2','A1',1,2019,1),
        ('T3','A1',1,2020,1),
        ('T4','A1',1,2020,2),
        ('T5','A1',1,2021,1)

    DECLARE @TEMP2 AS TABLE
        (
            SEG_ID NUMERIC(11,0),
            ACCOUNTNO VARCHAR(36),
            IMPNO NUMERIC(14,0),
            TAX_YEAR NUMERIC(4,0),
            ROWNUM NUMERIC(1,0)
        )
    INSERT INTO @TEMP2
    VALUES
        (1,'A1',1,2018,1),
        (2,'A1',1,2019,1),
        (3,'A1',1,2020,1),
        (4,'A1',1,2021,1),
        (5,'A1',1,2018,2),
        (6,'A1',1,2019,2),
        (7,'A1',1,2020,2),
        (8,'A1',1,2021,2)

    select TT.SEG_ID,TT.ACCOUNTNO,TT.IMPNO,TT.TAX_YEAR,oc.OCC_CODE
    FROM @TEMP2 TT
    left JOIN @TEMP OC
        ON TT.ACCOUNTNO = OC.ACCOUNTNO
        AND TT.IMPNO = OC.IMPNO
        AND TT.TAX_YEAR = OC.TAX_YEAR
        AND TT.ROWNUM = OC.ROWNUM
    ORDER BY TAX_YEAR,SEG_ID

Это возвращает:

введите описание изображения здесь

Я пытаюсь получить T1 в строке 2, T2 в строке 4 и T5 в строке 8.

Как вы можете видеть с TAX_YEAR 2020 иногда есть информация, которая должна соответствовать ROWNUM, которая отличается, поэтому я не могу удалить AND TT.ROWNUM = OC.ROWNUM

1 Ответ

2 голосов
/ 04 августа 2020

Если я вас правильно понимаю, боковое соединение (или подзапрос) с условием неравенства делает то, что вы хотите:

select 
    tt.seg_id,
    tt.accountno,
    tt.impno,
    tt.tax_year,
    oc.occ_code
from @temp2 tt
cross apply (
    select top (1) oc.occ_code
    from @temp oc
    where 
        tt.accountno = oc.accountno
        and tt.impno = oc.impno
        and tt.tax_year = oc.tax_year
        and tt.rownum >= oc.rownum
    order by oc.rownum desc
) oc
order by tax_year,seg_id

В основном боковое соединение ищет точное совпадение и возвращается к первое совпадение в меньшем rownum s.

Демо на DB Fiddle :

seg_id | accountno | impno | tax_year | occ_code
-----: | :-------- | ----: | -------: | :-------
     1 | A1        |     1 |     2018 | T1      
     5 | A1        |     1 |     2018 | T1      
     2 | A1        |     1 |     2019 | T2      
     6 | A1        |     1 |     2019 | T2      
     3 | A1        |     1 |     2020 | T3      
     7 | A1        |     1 |     2020 | T4      
     4 | A1        |     1 |     2021 | T5      
     8 | A1        |     1 |     2021 | T5      
...