Получить предыдущую запись, где дата не равна нулю - SQL SERVER - PullRequest
0 голосов
/ 17 октября 2018

У меня есть две таблицы, как показано ниже:

таблица 1:

ID  B   C   D   E   Date

1   b   c   D   E   2018/10/10
1   c   d   A   B   2018/10/14

Таблица 2:

ID  B   C   Date
1   b   c   2018/10/10
1   x   y   2018/10/11
1   y   x   2018/10/12
1   p   q   2018/10/13
1   c   d   2018/10/14

Таблица A имеет 6 столбцов, в то время как таблица 2 имеет 4 столбца.При использовании левого соединения получается:

Select * from Table2 t2 left join table1 t1
on t2.id=t1.id and t2.Date = t1.Date

Результат левого соединения:

ID  B   C   D   E   Date1           ID  B   C   Date2

1   b   c   D   E   2018/10/10      1   b   c   2018/10/10
-   -   -   -   -   -               1   x   y   2018/10/11
-   -   -   -   -   -               1   y   x   2018/10/12
    -   -   -   -   -               1   p   q   2018/10/13
1   c   d   A   B   2018/10/14      1   c   d   2018/10/14

Примечание:

  1. '-' represnt NULL.

  2. Даты отсортированы в результате левого соединения - упорядочены по table2.date, table1.date asc

  3. Я взял результат объединения в cte.не удалось сгенерировать окончательный результат.

Ожидаемый результат:

ID  B   C   D   E   Date

1   b   c   D   E   2018/10/10
1   x   y   D   E   2018/10/11
1   y   x   D   E   2018/10/12
1   p   q   D   E   2018/10/13
1   c   d   A   B   2018/10/14

Где Дата из таблицы1 равна нулю в левом результате соединения, поиск предыдущего ненулевая дата таблицы 1, которая будет чуть меньше текущей даты таблицы 2.

И извлекает значения столбцов D и E оттуда и сохраняет значения столбцов B и C из текущей записи, где Date1 равно нулю.

Будучи новичком в SQL, я застрял в этом.Пожалуйста, помогите.

Заранее спасибо.

Ответы [ 4 ]

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

Не могли бы вы проверить, является ли то, что вы ищете ниже,

Select t2.ID,t2.B,t2.C,t1.D,t1.E, t2.Date from Table2 t2 left join table1 t1
on t2.id=t1.id and (t2.Date >= t1.Date)
where not exists (select 1 from table1 t12 where t2.Date > t1.Date and t2.Date >= t12.Date and t12.Date > t1.Date)

Здесь мы попытались открыть таблицу 1 два раза (t1 и t12), чтобы убедиться, что дата в таблице 2 должна>= дата в таблице1 и <другая дата. </p>

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

Если вы используете SQL Server 2012 или более позднюю версию, следующий запрос возвращает ожидаемое вами значение.Я использовал функцию CTE и first_value(), и запрос оптимизирован .

with
    cte
as
(
    select
        t2.ID   ,
        t2.B    ,
        t2.C    ,
        t1.D    ,
        t1.E    ,
        t2.[Date]   ,
        sum(case when t1.D is null then 0 else 1 end) over (order by t2.[Date]) as D_partition,
        sum(case when t1.E is null then 0 else 1 end) over (order by t2.[Date]) as E_partition
    from
        Table2 t2
    left join
        table1 t1
    on
        t2.id = t1.id
        and
            t2.[Date] = t1.[Date]
)
select
    cte.ID  ,
    cte.B   ,
    cte.C   ,
    first_value(D) over(partition by D_partition order by D desc)   as D    ,
    first_value(E) over(partition by E_partition order by E desc)   as E    ,
    cte.Date
from
    cte;
0 голосов
/ 17 октября 2018

использование внешнее применение с верхом 1 .Это даст ваш результат, быстро и очень коротко:

-- create data from example:
-- ------------------------
select * into #Table1 from
(select 1 as ID, 'b' as B, 'c' as C, 'D' as D, 'E' as E, cast('2018-10-10' as date) as [Date]
union all select 1,   'c',   'd',   'A',   'B',   '2018-10-14')t

select * into #Table2 from
(select 1 as ID,   'b' as B,   'c' as C ,   cast('2018-10-10' as date) as [Date]
union all select 1,   'x',   'y',   '2018-10-11'
union all select 1,   'y',   'x',  '2018-10-12'
union all select 1,   'p',   'q',   '2018-10-13'
union all select 1,   'c',   'd',   '2018-10-14')t

-- SOLUTION
-- -------- 
select
    T2.ID,
    T2.B,
    T2.C,
    T1.D,
    T1.E,
    T2.[Date]
from
    #Table2 T2
    outer apply
    (
        select top 1 * from #Table1 T1
        where T1.ID=T2.ID and T1.[Date] <= T2.[Date]
        order by T1.[Date] desc
    ) T1


-- clean everything
-- ----------------
drop table #Table1
drop table #Table2
0 голосов
/ 17 октября 2018

Кажется, что вы оставили соединение table2 с таблицей 1, и вам нужны значения table1, если они существуют, иначе из table2.Это «если» на уровне данных обычно реализуется с помощью функции CASE.Тем не менее, в вашем случае мы можем использовать более конкретную функцию, ISNULL(a,b), которая возвращает a, когда a имеет значение, и b, когда a равно нулю:

select 
    t2.ID,
    isnull(t1.B,t2.B) as B,
    isnull(t1.C,t2.C) as C,
    isnull(t1.D,t2.D) as D,
    isnull(t1.E,t2.E) as E,
    isnull(t1.[Date],t2.[Date]) as [Date]
from Table2 t2 
left join table1 t1
on t2.id=t1.id and t2.Date = t1.Date

Однако вы уверены, что t2.Date = t1.Date нужно?Как правило, столбец с именем ID является уникальным / первичным ключом, так что это создает дополнительное условие соединения при избыточной дате.Вы должны удалить его, если это так.

...