Microsoft SQL 通过多个案例找到价格[已关闭]

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

我必须通过从层次结构中的 3 个选项中选择正确的价格来找到价格

从最高到最低

  1. 如果 trtype 是 Quot 则选择此价格
  2. 如果 Alvl 大于 0,则选择此价格而不是下面的价格
  3. 最后如果 trtype 都为空且 Alvl 为 0,则选择此价格(对于该客户,如果步骤 1 和 2 都为 false,则为级别 8)。

从 1 到 8 的所有“级别价格”都存储在空白客户中,但有多个价格记录,因此我需要提取这些记录的最新日期。

这是一个奇怪的查询,因为我选择一个客户(“测试”)来查看 [trtype] 和 [alvl],如果 [alvl] > 0 或 [trtype] 均为空白且 [alvl] 为 0,那么我必须在客户空白的情况下选择价格。

下面是当客户“测试”时我想要的查询结果

商品代码 乌姆 价格 开始日期 最终结果
ABC1234 EA 0.00 2024 年 1 月 15 日 29.57
X123456 CT 144.10 2024 年 5 月 15 日 144.10
BR23456 电脑 0.00 2024 年 1 月 1 日 15.56
CX23456 PNL 0.00 2024 年 1 月 1 日 15.36

下表是样本数据

的数据
create table pricing(Customer,itemcode,uom,trtype,Alvl,Blvl,price,start_date)as values
 ('test','ABC1234','EA','',6,0,0.0,'5/27/2024'::date)
,('test','X123456','CT','Quot',0,0,144.1,'5/15/2024')-----------
,('test','BR23456','PC','',0,0,0,'4/21/2024')
,('test','CX23456','PNL','',0,0,0,'4/21/2024')
,('lvlholder','ABC1234','EA','',0,3,44.9,'07/11/23')
,('lvlholder','ABC1234','EA','',0,3,44.9,'11/30/2023')
,('lvlholder','ABC1234','EA','',0,5,41.38,'07/11/23')
,('lvlholder','ABC1234','EA','',0,5,41.38,'11/30/2023')
,('lvlholder','ABC1234','EA','',0,2,34.81,'1/15/2024')
,('lvlholder','ABC1234','EA','',0,5,30.49,'1/15/2024')
,('lvlholder','ABC1234','EA','',0,8,28.39,'1/15/2024')
,('lvlholder','ABC1234','EA','',0,2,49.89,'07/11/23')
,('lvlholder','ABC1234','EA','',0,2,49.89,'11/30/2023')
,('lvlholder','ABC1234','EA','',0,7,37.24,'07/11/23')
,('lvlholder','ABC1234','EA','',0,7,37.24,'11/30/2023')
,('lvlholder','ABC1234','EA','',0,4,31.43,'1/15/2024')
,('lvlholder','ABC1234','EA','',0,7,28.97,'1/15/2024')
,('lvlholder','ABC1234','EA','',0,1,62.36,'07/11/23')
,('lvlholder','ABC1234','EA','',0,1,62.36,'11/30/2023')
,('lvlholder','ABC1234','EA','',0,8,36.5,'07/11/23')
,('lvlholder','ABC1234','EA','',0,8,36.5,'11/30/2023')
,('lvlholder','ABC1234','EA','',0,1,38.65,'1/15/2024')
,('lvlholder','ABC1234','EA','',0,3,33.05,'1/15/2024')
,('lvlholder','ABC1234','EA','',0,6,29.57,'1/15/2024')------------
,('lvlholder','ABC1234','EA','',0,4,42.66,'07/11/23')
,('lvlholder','ABC1234','EA','',0,4,42.66,'11/30/2023')
,('lvlholder','ABC1234','EA','',0,6,40.13,'07/11/23')
,('lvlholder','ABC1234','EA','',0,6,40.13,'11/30/2023')
,('lvlholder','X123456','CT','',0,1,251.68,'01/01/53')
,('lvlholder','X123456','CT','',0,2,201.52,'01/01/53')
,('lvlholder','X123456','CT','',0,3,191.4,'01/01/53')
,('lvlholder','X123456','CT','',0,4,181.72,'01/01/53')
,('lvlholder','X123456','CT','',0,5,176.22,'01/01/53')
,('lvlholder','X123456','CT','',0,6,170.94,'01/01/53')
,('lvlholder','X123456','CT','',0,7,165.88,'01/01/53')
,('lvlholder','X123456','CT','',0,8,156.63,'01/01/53')
,('lvlholder','BR23456','PC','',0,5,16.23,'07/05/23')
,('lvlholder','BR23456','PC','',0,5,16.23,'11/30/2023')
,('lvlholder','BR23456','PC','',0,8,14.82,'07/05/23')
,('lvlholder','BR23456','PC','',0,8,14.82,'11/30/2023')
,('lvlholder','BR23456','PC','',0,1,23.51,'07/05/23')
,('lvlholder','BR23456','PC','',0,1,23.51,'11/30/2023')
,('lvlholder','BR23456','PC','',0,3,17.99,'07/05/23')
,('lvlholder','BR23456','PC','',0,3,17.99,'11/30/2023')
,('lvlholder','BR23456','PC','',0,4,17.09,'07/05/23')
,('lvlholder','BR23456','PC','',0,4,17.09,'11/30/2023')
,('lvlholder','BR23456','PC','',0,3,18.89,'01/01/24')
,('lvlholder','BR23456','PC','',0,4,17.94,'01/01/24')
,('lvlholder','BR23456','PC','',0,5,17.04,'01/01/24')
,('lvlholder','BR23456','PC','',0,6,16.54,'01/01/24')
,('lvlholder','BR23456','PC','',0,7,16.04,'01/01/24')
,('lvlholder','BR23456','PC','',0,8,15.56,'01/01/24')--------
,('lvlholder','BR23456','PC','',0,2,19.99,'07/05/23')
,('lvlholder','BR23456','PC','',0,2,19.99,'11/30/2023')
,('lvlholder','BR23456','PC','',0,7,15.28,'07/05/23')
,('lvlholder','BR23456','PC','',0,7,15.28,'11/30/2023')
,('lvlholder','BR23456','PC','',0,1,24.69,'01/01/24')
,('lvlholder','BR23456','PC','',0,2,20.99,'01/01/24')
,('lvlholder','BR23456','PC','',0,6,15.75,'07/05/23')
,('lvlholder','BR23456','PC','',0,6,15.75,'11/30/2023')
,('lvlholder','CX23456','PNL','',0,1,24.38,'01/01/24')
,('lvlholder','CX23456','PNL','',0,2,19.74,'07/05/23')
,('lvlholder','CX23456','PNL','',0,2,19.74,'11/30/2023')
,('lvlholder','CX23456','PNL','',0,5,16.03,'07/05/23')
,('lvlholder','CX23456','PNL','',0,5,16.03,'11/30/2023')
,('lvlholder','CX23456','PNL','',0,7,15.09,'07/05/23')
,('lvlholder','CX23456','PNL','',0,7,15.09,'11/30/2023')
,('lvlholder','CX23456','PNL','',0,2,20.73,'01/01/24')
,('lvlholder','CX23456','PNL','',0,3,18.66,'01/01/24')
,('lvlholder','CX23456','PNL','',0,4,17.72,'01/01/24')
,('lvlholder','CX23456','PNL','',0,5,16.83,'01/01/24')
,('lvlholder','CX23456','PNL','',0,6,16.33,'01/01/24')
,('lvlholder','CX23456','PNL','',0,7,15.84,'01/01/24')
,('lvlholder','CX23456','PNL','',0,8,15.36,'01/01/24')------
,('lvlholder','CX23456','PNL','',0,8,14.63,'07/05/23')
,('lvlholder','CX23456','PNL','',0,8,14.63,'11/30/2023')
,('lvlholder','CX23456','PNL','',0,1,23.22,'07/05/23')
,('lvlholder','CX23456','PNL','',0,1,23.22,'11/30/2023')
,('lvlholder','CX23456','PNL','',0,3,17.77,'07/05/23')
,('lvlholder','CX23456','PNL','',0,3,17.77,'11/30/2023')
,('lvlholder','CX23456','PNL','',0,4,16.88,'07/05/23')
,('lvlholder','CX23456','PNL','',0,4,16.88,'11/30/2023')
,('lvlholder','CX23456','PNL','',0,6,15.55,'07/05/23')
,('lvlholder','CX23456','PNL','',0,6,15.55,'11/30/2023')
;
SELECT itemcode, uom, price, start_date,
    CASE
    WHEN trtype <> '' THEN price
    WHEN  alvl = 6 THEN /*XXXXXX?*/price
    ELSE 0
    END AS FinalResult
FROM pricing
WHERE customer = 'test'
ORDER BY start_date desc

我尝试添加一个选择,其中 XXXXXX 是,它告诉我我需要一个 WHERE EXIST,但这似乎不对。

我必须包含这 4 个项目的所有数据,以表明它必须为涉及前 2 个选项不是正确价格的项目选择最新日期。

sql postgresql subquery case
1个回答
0
投票

您可以使用

distinct on

db<>fiddle 的演示

select distinct on (itemcode,uom)
    itemcode
  , uom
  , price
  , start_date
from pricing
order by itemcode
       , uom
       , trtype='Quot' desc--if trtype is Quot than choose this price over all
       , alvl>0 desc--if Alvl is greater than 0 then choose this price over the one below
       , trtype='' and alvl=0 desc
       , blvl desc
       , start_date desc
  1. 您的预期结果与您描述的规则不一致:

    • 如果

      alvl>0
      优先于第三条规则,则此结果行:

      商品代码 乌姆 价格 开始日期 最终结果
      ABC1234 EA 0.00 2024 年 1 月 15 日 29.57

      应该是

      商品代码 乌姆 价格 开始日期 最终结果
      ABC1234 EA 0.00 27/05/2024 0.0
    • 最后两行,基于最后一条规则

      商品代码 乌姆 价格 开始日期 最终结果
      BR23456 电脑 0.00 2024 年 1 月 1 日 15.56
      CX23456 PNL 0.00 2024 年 1 月 1 日 15.36

      有比这两个更多的候选人,看起来你通过选择具有最高

      blvl
      的行来打破平局,如果有多个候选人,则最新的
      start_date
      获胜

  2. 这可能是因为您在设置为使用 Microsoft SQL Server 语法的随机编辑器中键入了伪代码示例,但方括号引用表明您是这样的,而不是 PostgreSQL。

    Distinct on
    特定于 PostgreSQL - 在 TSQL 中,您必须使用
    row_number()
    来模拟它。

  3. 尚不清楚您是否真的使用空字符串

    ''
    或实际的
    null
    来表示缺失值,但这是您应该披露的重要细节。它们不一样,而且工作原理也不一样。

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