英文:
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 '2023-01-01', DATE '2023-01-30' FROM DUAL
CREATE TABLE discount_history(customer_id, discount_date, discount_status) AS
SELECT 123, DATE '2022-12-27', 'ELIGIBLE' FROM DUAL UNION ALL
SELECT 123, DATE '2023-01-10', 'INELIGIBLE' FROM DUAL UNION ALL
SELECT 123, DATE '2023-01-19', 'ELIGIBLE' FROM DUAL UNION ALL
SELECT 123, DATE '2023-01-27', 'INELIGIBLE' 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 '2999-12-31')
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 = 'ELIGIBLE'
and i.date_from <= p.discount_end_date
and i.date_to >= 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 = '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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论