SQL Join on Nearest less than date

匿名 (未验证) 提交于 2019-12-03 01:12:01

问题:

Normally I would just do this in the code itself, but I am curious if this can be accomplished efficiently in TSQL.

Table 1  Date - Value
Table 2 Date - Discount

Table 1 contains entries for each day. Table 2 contains entries only when the discount changes. A discount applied to a value is considered valid until a new discount is entered.

Example data:

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  

What I need returned is the following: T1 Date - T1 Value - T2 Discount

Example data:

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  

Possible or am I better off just continuing to do this in the code?

回答1:

I believe this subquery will do it (not tested).

select *,     (select top 1 Discount      from table2      where table2.Date 

Perhaps not the most performant however.

Edit:

Test code:

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] 

Results:

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


回答2:

No "nearest" query is going to be as efficient as an "equals" query, but this is another job for the trusty 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] 


回答3:

This works on oracle XE. Since sql server does have analytic functions, it shouldn't be to difficult to port it.

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)  )


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!