SQL加入时间小于最近的日期

问题描述 投票:25回答:4

通常我只是在代码本身中这样做,但是我很好奇这是否可以在TSQL中有效地完成。

表1日期-值
表2日期-折扣

表1包含每天的条目。表2仅包含折扣更改时的条目。在输入新折扣之前,应用于值的折扣才被视为有效。

示例数据:

表12010年1月6日-102010年1月25日-92010年1月4日-82010年1月4日-92010/1/23-72010年1月2日-102010年1月1日-11
表22010年1月6日-22010年1月3日-12010年1月20日-0

我需要返回以下内容:T1 Date - T1 Value - T2 Discount

示例数据:

2010年1月6日-10-22010年1月25日-9-12010年1月4日-8-12010年1月24日-9-12010/1/23-7-12010年1月2日-10-02010年1月1日-11-0

可能还是我最好还是继续在代码中这样做?

sql sql-server sql-server-2005
4个回答
25
投票

我相信此子查询可以做到(未测试)。

select *, 
   (select top 1 Discount 
    from table2 
    where table2.Date <= t.Date 
    order by table2.Date desc) as Discount
from Table1 t

但是也许不是表现最好的。

编辑:

测试代码:

create table #table1 ([date] datetime, val int)
create table #table2 ([date] datetime, discount int)

insert into #table1 ([date], val) values ('1/26/2010', 10)
insert into #table1 ([date], val) values ('1/25/2010', 9)
insert into #table1 ([date], val) values ('1/24/2010', 8)
insert into #table1 ([date], val) values ('1/24/2010', 9)
insert into #table1 ([date], val) values ('1/23/2010', 7)
insert into #table1 ([date], val) values ('1/22/2010', 10)
insert into #table1 ([date], val) values ('1/21/2010', 11)

insert into #table2 ([date], discount) values ('1/26/2010', 2)
insert into #table2 ([date], discount) values ('1/23/2010', 1)
insert into #table2 ([date], discount) values ('1/20/2010', 0)

select *, 
   (select top 1 discount 
    from #table2 
    where #table2.[date] <= t.[date]
    order by #table2.[date] desc) as discount
from #table1 t

drop table #table1
drop table #table2

2010-01-26 00:00:00.000 10 22010-01-25 00:00:00.000 9 12010-01-24 00:00:00.000 8 12010-01-24 00:00:00.000 9 12010-01-23 00:00:00.000 7 12010-01-22 00:00:00.000 10 02010-01-21 00:00:00.000 11 0


19
投票
没有“最近”查询将与“等于”查询一样有效,但这是值得信赖的ROW_NUMBER的另一项工作:

;WITH Discounts_CTE AS ( SELECT t1.[Date], t1.[Value], t2.Discount, ROW_NUMBER() OVER ( PARTITION BY t1.[Date] ORDER BY t2.[Date] DESC ) AS RowNum FROM Table1 t1 INNER JOIN Table2 t2 ON t2.[Date] <= t1.[Date] ) SELECT * FROM Discounts_CTE WHERE RowNum = 1


0
投票
这适用于oracle XE。由于sql server确实具有分析功能,因此移植它应该不难。

create table one ( day date, value integer ); create table two ( day date, discount integer ); insert into one values (trunc(sysdate), 10); insert into one values (trunc(sysdate-1), 8); insert into one values (trunc(sysdate-2), 1); insert into one values (trunc(sysdate-3), 23); insert into one values (trunc(sysdate-4), 3); insert into one values (trunc(sysdate-5), 4); insert into one values (trunc(sysdate-6), 8); insert into one values (trunc(sysdate-7), 5); insert into one values (trunc(sysdate-8),8); insert into one values (trunc(sysdate-9), 8); insert into one values (trunc(sysdate-10), 5); insert into two values (trunc(sysdate), 2); insert into two values (trunc(sysdate-3), 1); insert into two values (trunc(sysdate-5), 3); insert into two values (trunc(sysdate-8), 1); select day, value, discount, cnt, nvl(max(discount) over (partition by cnt) ,0) as calc_discount from ( select day, value, discount, count(discount) over (order by day) as cnt from one left outer join two using(day) )


0
投票
添加到Joels答案...如果两个表中都存在ID,以下内容将提高性能:

select *, (select top 1 Discount from Table2 t2 where t2.Date <= t1.Date and t2.ID = t1.ID order by t2.Date desc) as Discount from Table1 t1

© www.soinside.com 2019 - 2024. All rights reserved.