ПРИСОЕДИНЯЙТЕСЬ, когда данных не существует

#sql #join #db2

Вопрос:

Отказ от ответственности: У меня нет большого технического образования, и я просто изучаю SQL, поэтому приношу свои извинения. У меня есть 2 таблицы для информации acct — одни данные ref (ACCT_RD) и одни данные txn (ACCT_TD).

ACCT_RD выглядит так

ACCT_ID ACCT_NAME
1 азбука
2 xyz

ACCT_TD выглядит так

ACCT_ID Дата ценность
1 01-31-2020 4000.33
1 01-31-2021 2000.11
2 01-31-2020 5666.23

Мне нужен запрос, в котором я передам идентификатор учетной записи и дату, и он вернет мне данные в формате

ACCT_ID Имя Дата ценность
1 азбука 01-31-2020 4000.33
1 азбука нулевой нулевой

возможно, ACCT_TD может не содержать данных (строк) для всех дат, но ACCT_RD всегда будет содержать информацию.

Я пытаюсь присоединиться СЛЕВА, как

 SELECT R.ACCT_ID, R.NAME, T.VALUE, T.DATE
FROM ACCT_RD R
    LEFT JOIN ACCT_TD T ON R.ACCT_ID = T.ACCT_ID
WHERE R.ACCT_ID = 1
  AND T.DATE IN ('01-31-2000','01-31-2020')
 

Я получаю строку, в которой у меня есть данные в обоих, и ни одной строки, в которой у меня нет данных в ACCT_TD.

Это потому, что в ACCT_TD не существует строки для даты «01-31-2000», и это не столбец для ACCT_RD?

Как я могу достичь того, что я ищу?

Ответ №1:

Похоже, у вас есть следующие требования к набору результатов.

  • Для любого заданного ACCT_ID он должен содержать все соответствующие строки (если таковые имеются) из ACCT_TD
  • Столбцы результирующего набора значений и ДАТ равны ACCT_TD.VALUE и ACCT_TD.DATE , если ACCT_TD.DATE есть в списке переданных параметров даты, и оба равны НУЛЮ в противном случае

Если это правильное понимание требований, то попробуйте это:

 WITH 
  ACCT_RD (ACCT_ID, ACCT_NAME) AS
(
VALUES
  (1, 'abc')
, (2, 'xyz')
)
, ACCT_TD (ACCT_ID, DATE, VALUE) AS
(
VALUES
  (1, '01-31-2020', 4000.33)
, (1, '01-31-2021', 2000.11)
, (2, '01-31-2020', 5666.23)
)
SELECT 
  R.ACCT_ID, R.ACCT_NAME
, CASE WHEN T.DATE IN ('01-31-2000','01-31-2020') THEN T.DATE  END AS DATE
, CASE WHEN T.DATE IN ('01-31-2000','01-31-2020') THEN T.VALUE END AS VALUE
FROM ACCT_RD R
LEFT JOIN ACCT_TD T ON R.ACCT_ID = T.ACCT_ID
WHERE R.ACCT_ID = 1;
 

В результате получается:

 |ACCT_ID|ACCT_NAME|DATE      |VALUE  |
|-------|---------|----------|-------|
|1      |abc      |01-31-2020|4000.33|
|1      |abc      |          |       |
 

Ответ №2:

Если вы хотите гарантировать, что одна строка будет возвращена, даже если во второй таблице нет совпадения, просто переместите фильтры дат в on предложение:

 SELECT R.ACCT_ID, R.NAME, T.VALUE, T.DATE
FROM ACCT_RD R LEFT JOIN
     ACCT_TD T
     ON R.ACCT_ID = T.ACCT_ID AND
        T.DATE IN ('01-31-2000', '01-31-2020')
WHERE R.ACCT_ID = 1;
 

Значения будут NULL такими, если совпадения нет.

Кроме того, если ваши столбцы действительно являются датами, вам следует использовать правильные форматы дат:

         T.DATE IN ('2000-01-31', '2000-01-31')