可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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) )