我有两张桌子。销售额和产品率。
销售情况如下:
身份证 | SurogateKey | 交易日期 |
---|---|---|
1 | 343 | 2020-09-01T00:00:00 |
2 | 3 | 2020-08-01T00:00:00 |
3 | 3 | 2020-10-01T00:00:00 |
4 | 96 | 2020-09-01T00:00:00 |
5 | 343 | 2020-01-01T00:00:00 |
产品价格:
身份证 | 价格 | 开始日期 |
---|---|---|
343 | 95.2 | 2020-09-01T00:00:00 |
3 | 87.2 | 2020-08-01T00:00:00 |
3 | 3 | 2020-09-01T00:00:00 |
3 | 96 | 2020-09-01T00:00:00 |
343 | 343 | 2020-01-01T00:00:00 |
我想知道的是特定销售的价格:
这是我对场景 1 的逻辑:
select *
from sales as s
left join producct rate as pr
on s.SurogateKey = pr.Id
and s.TransactionDate between pr.StartDate and eomonth(pr.StartDate)
但是,我如何获得那些在给定月份没有 StartDate 的人的最新记录。
身份证 | SurogateKey | 交易日期 | 价格 |
---|---|---|---|
1 | 343 | 2020-09-01T00:00:00 | 95.2 |
2 | 3 | 2020-08-01T00:00:00 | 87.2 |
** 3** | 3 | 2020-10-01T00:00:00 | 3 |
4 | 96 | 2020-09-01T00:00:00 | 空 |
5 | 343 | 2020-01-01T00:00:00 | 343 |
我觉得是这样的:
select *
from sales as s
left join producct rate as pr
on s.SurogateKey = pr.Id
and (
s.TransactionDate between pr.StartDate and eomonth(pr.StartDate)
or (
s.TransactionDate not between pr.StartDate and eomonth(pr.StartDate)
and S.TransactionDate > pr.StartDate
)
)
我做错了什么?
DBFIDLE
以下内容满足您的要求。使用
outer apply
选择要加入的正确 ProductRate
。然后使用优先级 order by
首先从窗口内选择速率,如果没有,则仅选择最新的速率。
我通常会使用带有查询的
left join
来选择要加入的正确行,但与您不同的是,您的 ProductRate
表上似乎没有唯一键,因此联接选项不起作用.
declare @Sale table (id int, SurogateKey int, TransactionDate datetime);
insert into @Sale (Id, SurogateKey, TransactionDate)
values
(1,343,'2020-09-01T00:00:00'),
(2,3,'2020-08-01T00:00:00'),
(3,3,'2020-10-01T00:00:00'),
(4,96,'2020-09-01T00:00:00'),
(5,343,'2020-01-01T00:00:00');
declare @ProductRate table (id int, Rate decimal(9,2), StartDate datetime);
insert into @ProductRate (id, Rate, StartDate)
values
(343,95.2,'2020-09-01T00:00:00'),
(3,87.2,'2020-08-01T00:00:00'),
(3,3,'2020-09-01T00:00:00'),
(3,96,'2020-09-01T00:00:00'),
(343,343,'2020-01-01T00:00:00');
select S.id, S.SurogateKey, S.TransactionDate, PR1.Rate, PR1.StartDate
from @Sale S
outer apply (
select top 1 Rate, StartDate
from @ProductRate PR
where PR.id = S.SurogateKey
order by case when S.TransactionDate >= PR.StartDate and S.TransactionDate < dateadd(day, 1, eomonth(PR.StartDate)) then 1 else 0 end desc
, PR.StartDate desc
) PR1 (Rate, StartDate);
退货:
id | SurogateKey | 交易日期 | 价格 | 开始日期 |
---|---|---|---|---|
1 | 343 | 2020-09-01 00:00:00.000 | 95.20 | 2020-09-01 00:00:00.000 |
2 | 3 | 2020-08-01 00:00:00.000 | 87.20 | 2020-08-01 00:00:00.000 |
3 | 3 | 2020-10-01 00:00:00.000 | 3.00 | 2020-09-01 00:00:00.000 |
4 | 96 | 2020-09-01 00:00:00.000 | 空 | 空 |
5 | 343 | 2020-01-01 00:00:00.000 | 343.00 | 2020-01-01 00:00:00.000 |
注意:我不是
between
的粉丝,它的行为不直观(IMO),并且在使用 datetime
而不是 date
时无法按预期工作。我更喜欢如图所示的手动构建的窗口。