查找客户发票的合格日期,基于其折扣历史记录。

huangapple go评论79阅读模式
英文:

Find the eligible days of a customer's invoice based on its discount history

问题

以下是发票以及相应的日期范围:

查找客户发票的合格日期,基于其折扣历史记录。

这里是折扣历史记录:

查找客户发票的合格日期,基于其折扣历史记录。

现在,我需要一个SQL查询逻辑,以找出第一个表中的invoiceid有资格的天数,基于折扣历史表。

计算如下:
invoiceid 229的日期范围分解如下
--> 01-01-23到10-01-2023 = 10天有资格
以及19-01-23到27-01-2023 = 9天有资格

所以折扣的总有资格天数= 19天

英文:

Here is the below invoice and having corresponding datefrom and dateto
查找客户发票的合格日期,基于其折扣历史记录。

Here the discount history

查找客户发票的合格日期,基于其折扣历史记录。

Now I need a sql query logic to find out number of days the invoiceid on the first table is eligible, based on the discount history table.

calculation as follows:
invoiceid 229 datefrom and dateto breakdown
--> 01-01-23 to 10-01-2023 = 10 days eligible
and 19-01-23 to 27-01-2023 = 9 days eligible

so total eligible days of the discount = 19 days

答案1

得分: 0

你真的不应该发布屏幕截图,因为想要帮助的人更愿意避免输入您的数据。将来请提供必要的数据,以便他人可以直接将其剪切并粘贴到SQLPLUS中。

话虽如此,我认为数据应该意味着该帐户从2022年12月27日至2023年01月09日符合条件;在2023年01月10日,该帐户将不符合条件。

以下是您可以使用并根据需要调整的内容。


创建表单据(客户ID, 发票ID, 开始日期, 结束日期) 作为
从DUAL中选择123, 229,日期 '2023-01-01', 日期 '2023-01-30' 

创建折扣历史(客户ID, 折扣日期, 折扣状态) 作为
从DUAL中选择123, 日期 '2022-12-27', '符合条件' UNION ALL 
从DUAL中选择123, 日期 '2023-01-10', '不符合条件' UNION ALL 
从DUAL中选择123, 日期 '2023-01-19', '符合条件' UNION ALL 
从DUAL中选择123, 日期 '2023-01-27', '不符合条件'

带
  准备 (客户ID, 折扣日期, 折扣状态, 折扣结束日期) 作为 (
    从折扣历史中选择客户ID, 折扣日期, 折扣状态, 
           lead(折扣日期, 1, 日期 '2999-12-31')
                在 (按客户ID分组折扣日期顺序排列) 上
           - 1
    从折扣历史中
  )
从   发票 i 加入 准备 p
         在    i.客户ID = p.客户ID
           和 p.折扣状态 = '符合条件'
           和 i.开始日期 <= p.折扣结束日期 
           和 i.结束日期   > p.折扣日期
组
           按 i.客户ID
;

客户ID  折扣天数
123                  17

英文:

You really shouldn't post screen shots as people that want to help would prefer not to enter your data too. In the future please provide the necessary data where others can just cut and paste it into SQLPLUS

Having said that, I believe data should mean that the account is eligible from 2022-12-27 until 2023-01-09; on 2023-01-10 the account becomes ineligible.

Here is something you can work with and adjust as needed.


CREATE TABLE invoices(customer_id, invoice_id, date_from, date_to) AS
SELECT 123, 229,DATE &#39;2023-01-01&#39;, DATE &#39;2023-01-30&#39; FROM DUAL 


CREATE TABLE discount_history(customer_id, discount_date, discount_status) AS
SELECT 123, DATE &#39;2022-12-27&#39;, &#39;ELIGIBLE&#39; FROM DUAL UNION ALL 
SELECT 123, DATE &#39;2023-01-10&#39;, &#39;INELIGIBLE&#39; FROM DUAL UNION ALL 
SELECT 123, DATE &#39;2023-01-19&#39;, &#39;ELIGIBLE&#39; FROM DUAL UNION ALL 
SELECT 123, DATE &#39;2023-01-27&#39;, &#39;INELIGIBLE&#39; FROM DUAL

with
  prep (customer_id, discount_date, discount_status, discount_end_date) as (
    select customer_id, discount_date, discount_status, 
           lead(discount_date, 1, date &#39;2999-12-31&#39;)
                over (partition by customer_id order by discount_date) - 1
    from   discount_history
  )
select i.customer_id,
       sum(least(i.date_to, p.discount_end_date) - greatest(i.date_from, p.discount_date) + 1)
         as discount_days
 from   invoices i join prep p
         on    i.customer_id = p.customer_id
           and p.discount_status = &#39;ELIGIBLE&#39;
           and i.date_from &lt;= p.discount_end_date 
           and i.date_to   &gt;= p.discount_date
group   by i.customer_id
;


customer_id  discount_days
123                  17

答案2

得分: 0

如果您需要考虑可能存在的数据质量问题,比如连续出现多个相同的discount_status:

with merged_history(customer_id, start_dat, end_dat) as (
    select * from discount_history
    match_recognize (
        partition by customer_id
        order by discount_date,  discount_status
        measures first(eligible.discount_date) as start_eligible, 
            first(ineligible.discount_date) as end_inineligible
        pattern( eligible+ ineligible+ )
        define
            eligible as discount_status = 'ELIGIBLE',
            ineligible as discount_status = 'INELIGIBLE'
    )
)
select inv.customer_id,
    sum(least(inv.date_to, hist.end_dat) - greatest(inv.date_from, hist.start_dat)) as discount_days
from invoices inv
join merged_history hist on inv.customer_id = hist.customer_id;

123 17

英文:

If you need to take into account possible data quality issues like several identical discount_status consecutive:

with merged_history(customer_id, start_dat, end_dat) as (
	select * from discount_history
	match_recognize (
		partition by customer_id
		order by discount_date,  discount_status
		measures first(eligible.discount_date) as start_eligible, 
			first(ineligible.discount_date) as end_inineligible
		pattern( eligible+ ineligible+ )
		define
			eligible as discount_status = &#39;ELIGIBLE&#39;,
			ineligible as discount_status = &#39;INELIGIBLE&#39;
	)
)
select inv.customer_id,
	sum(least(inv.date_to, hist.end_dat) - greatest(inv.date_from, hist.start_dat)) as discount_days
from invoices inv
join merged_history hist on inv.customer_id = hist.customer_id;



123	17

huangapple
  • 本文由 发表于 2023年7月27日 21:06:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/76780052.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定