SQL加入最近的日期

Pan*_*her 28 sql sql-server sql-server-2005

通常我会在代码本身中执行此操作,但我很好奇是否可以在TSQL中有效地完成此操作.

Table 1 
Date - Value
Table 2
Date - Discount

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

示例数据:

Table 1  
1/26/2010 - 10  
1/25/2010 - 9  
1/24/2010 - 8  
1/24/2010 - 9   
1/23/2010 - 7    
1/22/2010 - 10  
1/21/2010 - 11
Table 2
1/26/2010 - 2  
1/23/2010 - 1  
1/20/2010 - 0  

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

示例数据:

1/26/2010 - 10 - 2    
1/25/2010 - 9  - 1  
1/24/2010 - 8  - 1  
1/24/2010 - 9  - 1  
1/23/2010 - 7  - 1    
1/22/2010 - 10 - 0  
1/21/2010 - 11 - 0  

可能还是我最好继续在代码中执行此操作?

Joe*_*oel 27

我相信这个子查询会做(未经测试).

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

然而,也许不是最高效的.

编辑:

测试代码:

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
Run Code Online (Sandbox Code Playgroud)

结果:

2010-01-26 00:00:00.000 10  2
2010-01-25 00:00:00.000 9   1
2010-01-24 00:00:00.000 8   1
2010-01-24 00:00:00.000 9   1
2010-01-23 00:00:00.000 7   1
2010-01-22 00:00:00.000 10  0
2010-01-21 00:00:00.000 11  0


Aar*_*ght 21

没有"最近"的查询会像"等于"查询一样高效,但这是可信赖的另一项工作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
Run Code Online (Sandbox Code Playgroud)


xxy*_*oel 5

添加到 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
Run Code Online (Sandbox Code Playgroud)

  • “乔尔斯答案”可能会改变或消失。写下你的独立答案。 (3认同)
  • @HackSlash (1)“joels 答案”是公认的答案,它不太可能消失;参考别人的答案并不罕见。(2) 答案是独立的...? (2认同)