
[英]SQL query to create a view with additional column based on successive row values
[英]create additional date after and before current row and create new column based on it
可以说我有这种数据
create table example
(cust_id VARCHAR, product VARCHAR, price float, datetime varchar);
insert into example (cust_id, product, price, datetime)
VALUES
('1', 'scooter', 2000, '2022-01-10'),
('1', 'skateboard', 1500, '2022-01-20'),
('1', 'beefmeat', 300, '2022-06-08'),
('2', 'wallet', 200, '2022-02-25'),
('2', 'hairdryer', 250, '2022-04-28'),
('3', 'skateboard', 1600, '2022-03-29')
我想制作一些额外的行,然后根据这些额外的行制作新的列
我的期望 output 会喜欢这个
客户编号 | 总价 | 日期 | 活跃 |
---|---|---|---|
1个 | 3500 | 2022-01 | 积极的 |
1个 | 0 | 2022-02 | 积极的 |
1个 | 0 | 2022-03 | 积极的 |
1个 | 0 | 2022-04 | 不活跃 |
1个 | 0 | 2022-05 | 不活跃 |
1个 | 300 | 2022-06 | 积极的 |
1个 | 0 | 2022-07 | 积极的 |
2个 | 0 | 2022-01 | 不活跃 |
2个 | 200 | 2022-02 | 积极的 |
2个 | 0 | 2022-03 | 积极的 |
2个 | 250 | 2022-04 | 积极的 |
2个 | 0 | 2022-05 | 积极的 |
2个 | 0 | 2022-06 | 积极的 |
2个 | 0 | 2022-07 | 不活跃 |
3个 | 0 | 2022-01 | 不活跃 |
3个 | 0 | 2022-02 | 不活跃 |
3个 | 1600 | 2022-03 | 积极的 |
3个 | 0 | 2022-04 | 积极的 |
3个 | 0 | 2022-05 | 积极的 |
3个 | 0 | 2022-06 | 不活跃 |
3个 | 0 | 2022-07 | 不活跃 |
规则是这样的
好吧,我的第一个想法是使用这段代码,但我不知道下一步是什么
select *,
date_part('month', age(to_date(date, 'YYYY-MM'), to_date(lag(date) over (partition by cust_id order by date),'YYYY-MM')))date_diff
from(
select
cust_id,
sum(price)total_price,
to_char(to_date(datetime, 'YYYY-MM-DD'),'YYYY-MM')date
from example
group BY
cust_id,
date
order by
cust_id,
date)test
我愿意接受任何建议
尝试以下,查询评论中的解释:
/* use generate_series to generate a series of dates
starting from the min date of datetime up to the
max datetime with one-month intervals, then do a
cross join with the distinct cust_id to map each cust_id
to each generated date.*/
WITH cust_dates AS
(
SELECT EX.cust_id, to_char(dts, 'YYYY-mm') dts
FROM generate_series
(
(SELECT MIN(datetime)::timestamp FROM example),
(SELECT MAX(datetime)::timestamp + '2 month'::interval FROM example),
'1 month'::interval
) dts
CROSS JOIN (SELECT DISTINCT cust_id FROM example) EX
),
/* do a left join with your table to find prices
for each cust_id/ month, and aggregate for cust_id, month_date
to find the sum of prices for each cust_id, month_date.
*/
monthly_price AS
(
SELECT CD.cust_id,
CD.dts AS month_date,
COALESCE(SUM(price), 0) total_price
FROM cust_dates CD LEFT JOIN example EX
ON CD.cust_id = EX.cust_id AND
CD.dts = to_char(EX.datetime, 'YYYY-mm')
GROUP BY CD.cust_id, CD.dts
)
/* Now, we have the sum of monthly prices for each cust_id,
we can use the max window function with "ROWS BETWEEN 2 PRECEDING AND CURRENT ROW"
to check if one of the (current month or the previous two months) has a sum of prices > 0.
*/
SELECT cust_id, month_date, total_price,
CASE MAX(total_price) OVER
(PARTITION BY cust_id ORDER BY month_date
ROWS BETWEEN 2 PRECEDING AND CURRENT ROW)
WHEN 0 THEN 'inactive'
ELSE 'active'
END AS is_active
FROM monthly_price
ORDER BY cust_id, month_date
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.