当语句间条件不满足时默认为最新记录?

问题描述 投票:0回答:1

我有两张桌子。销售额和产品率。

销售情况如下:

身份证 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. 申请的 StartDate 到月底
  2. 在没有 StartDate 的情况下,可以采用最新的日期并使用它。

这是我对场景 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

https://www.db-fiddle.com/f/dgFkhVhs7KjLgu5H2NS8Fm/0

https://i.stack.imgur.com/JPeay.png

sql sql-server t-sql apache-spark-sql
1个回答
1
投票

以下内容满足您的要求。使用

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
时无法按预期工作。我更喜欢如图所示的手动构建的窗口。

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