我有两个表格,如下所示:
表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
注意:
'-'表示NULL。
日期按左连接结果排序-按table2.date排序, table1.date asc
预期结果:
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
如果左联接结果中table1的Date为null,则搜索表1的先前非null日期,该日期将小于表2的当前日期。
然后从那里获取D和E列的值,并从Date1为空的当前记录中保留B和C列的值。
作为sql的新手,我陷入了困境。请帮忙。
谢谢。
答案 0 :(得分:1)
如果您使用的是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;
答案 1 :(得分: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
答案 2 :(得分:0)
似乎您将table2连接到表1,并且想要table1的值(如果存在),否则想要来自table2的值。数据级别的“ if”通常是通过CASE
函数实现的。但是,根据您的情况,我们可以使用更具体的函数ISNULL(a,b)
,当a具有值时返回a,而当a为空时返回b:
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
的列是唯一/主键,因此这将使日期的附加联接条件变得多余。在这种情况下,您应该删除它。
答案 3 :(得分:0)
您可以检查一下是否在寻找以下内容吗?
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中的日期而<其他日期。