Фильтрация данных на основе динамической даты - PullRequest
0 голосов
/ 15 сентября 2018
Create table #TEMP
(
ID INT
)

Create table #TEMP1
(
ID      INT,
Letter_Type   VARCHAR(100),
Letter_Sent_Date  DATE
)

INSERT INTO #TEMP VALUES (1),(2),(3),(4)
GO

INSERT INTO #TEMP1 VALUES
(1,'A','01/01/2017'),
(1,'B','01/02/2017'),
(1,'C','01/03/2018'),
(1,'D','01/04/2018'),
(2,'A','01/01/2017'),
(2,'B','01/02/2017'),
(2,'C','01/10/2018'),
(2,'D','01/12/2018')

Я пытаюсь добиться следующих результатов - данные должны основываться на дате.

Предположим, я хочу знать любое письмо, отправленное после '01 / 05/2018 'для типа письма C. Для идентификатора 1 нет буквы C - в этом случае нам нужно напечатать нулевое значение.

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

Любая помощь очень ценится.Спасибо!

OUTPUT
1,NULL,NULL
2,C,'01/10/2018'

Ответы [ 2 ]

0 голосов
/ 01 октября 2018

В попытке избежать не существующего / не существующего решения, может быть, это может вам помочь?

WITH TEMP (ID, LETTER_TYPE, LETTER_SENT_DATE) AS
     (select 1, 'A', date '2017-01-01' from dual union all
      SELECT 1, 'B', DATE '2017-02-01' FROM DUAL UNION ALL
      --SELECT 1, 'C', DATE '2018-03-01' FROM DUAL UNION ALL
      select 1, 'D', date '2018-04-01' from dual union all

      select 2, 'A', date '2017-01-01' from dual union all
      SELECT 2, 'B', DATE '2017-02-01' FROM DUAL UNION ALL
      SELECT 2, 'C', DATE '2018-10-01' FROM DUAL UNION ALL
      select 2, 'D', date '2018-12-01' from dual
     )
     SELECT ID, LETTER_TYPE, LETTER_SENT_DATE FROM TEMP
     WHERE LETTER_SENT_DATE > DATE '2018-05-01'
     AND LETTER_TYPE = 'C'
     UNION
    SELECT ID, NULL LETTER_TYPE, NULL LETTER_SENT_DATE
    from (
    select tt.id , sum(tt.HASLETTER) hasletter
    FROM 
     (SELECT T1.ID,  CASE WHEN (T1.LETTER_TYPE='C') THEN 1 ELSE 0 END HASLETTER --, NULL T1.LETTER_SENT_DATE 
     FROM TEMP T1) TT
     GROUP BY TT.ID
     ) hl

    where hl.hasletter = 0
0 голосов
/ 15 сентября 2018

Это довольно неуклюжий , но я думаю, что он возвращает то, что вы хотите (написано в Oracle).

CTE (условие факторизации WITH) используется для подготовки тестовых данных;вам это не нужно, поскольку ваши данные уже находятся в этих двух таблицах).Полезный код начинается со строки 15;взгляните на комментарии.

SQL> with
  2  temp (id) as
  3    (select level from dual connect by level <= 4),
  4  temp1 (id, letter_type, letter_sent_date) as
  5    (select 1, 'A', date '2017-01-01' from dual union all
  6     select 1, 'B', date '2017-01-02' from dual union all
  7     select 1, 'C', date '2018-01-03' from dual union all
  8     select 1, 'D', date '2018-01-04' from dual union all
  9     --
 10     select 2, 'A', date '2017-01-01' from dual union all
 11     select 2, 'B', date '2017-01-02' from dual union all
 12     select 2, 'C', date '2018-01-10' from dual union all
 13     select 2, 'D', date '2018-01-12' from dual
 14    ),
 15  -- letter type = 'C' and letters were sent after 2018-01-05
 16  satisfy_condition as
 17    (select t.id, t1.letter_type, t1.letter_sent_date
 18     from temp t join temp1 t1 on t1.id = t.id
 19     where t1.letter_type = 'C'
 20       and t1.letter_sent_date > date '2018-01-05'
 21    )
 22  -- Finally: rows that satisfy condition ...
 23  select i.id, i.letter_type, i.letter_sent_date
 24  from satisfy_condition i
 25  union
 26  -- ... and rows that contain letter type = 'C', but were sent before 2018-01-05
 27  select t.id, null, null
 28  from temp1 t
 29  where t.letter_type = 'C'
 30    and t.id not in (select i1.id from satisfy_condition i1)
 31  order by id, letter_type, letter_sent_date;

        ID LETTER_TYPE  LETTER_SENT_DATE
---------- ------------ --------------------
         1
         2 C            2018-01-10

SQL>
...