表中每个月份对应单价不一定存在,需要在有本月单价时就取本月单价,没有本月单价时就取小于本月并离本月最近月份的单价。
例如该物料在1月份有定价,11月份有定价,本月为10月如果本月又重新定价则去该月份的单价,没有的话就取1月份的定价,可能存在12月份只有个别月份没定价的情况,统一取上月或者之前月份的最新定价。
注:定价表有记账期间字段和价格字段,其他字段用不到
讲下思路,首先我试了下case when 筛选 求出最近期间的最新定价,求最近期间号的公式是
select max(账簿期间号) from (select CASE WHEN 账簿期间号=RIGHT('${日期}',2) AND RIGHT(会计期间,2)=RIGHT('${日期}',2) THEN 账簿期间号 WHEN 账簿期间号<RIGHT('${日期}',2) AND RIGHT(会计期间,2)<RIGHT('${日期}',2) THEN max(账簿期间号) END 账簿期间号 from 料品表,期间价格表,其他表(都有唯一键作为连接条件)
where 主表.料号=子表.料号 and 主表的其他条件。
日期参数的值只有年和月,发现由于价格不同会出现两个或两个以上的排序之后的结果,所以改良为上面的sql语句作为主查询的条件子查询令主表的账簿期间号=子表查出的最近期间的期间号,子表只用账簿期间号作为筛选时就不会因为价格不同出现多个结果,其中子查询的条件和主查询一致,多了一个连接条件为主查询的料号=子查询的料号,保证数据的正常展示。最终结果为
难点:保证账簿期间号的唯一性正确性,同时还要保证和主表有唯一的联系,否则数据会出现无效或者查询进入未知情况时间过长或者数据错乱
什么数据库:oracle?SqlServer?mysql?
--sql server
with a as(
select '2022-09' as 期间,'a' as 类型 ,5 as 单价
union all
select '2022-10' as 期间,'a' as 类型 ,4 as 单价
select '2022-08' as 期间,'b' as 类型 ,3 as 单价
select '2022-06' as 期间,'b' as 类型 ,2 as 单价
),
b as (
select * ,ROW_NUMBER()over(partition by 类型 order by 期间 desc) as 序号 from a
)
select * from b where b.序号=1