sql - 从日期范围获取连续的月份和天数?
问题描述
所以假设我有一张这样的桌子:
订阅者 ID | package_id | package_start_date | 包裹结束日期 | package_price_per_day |
---|---|---|---|---|
1081 | 231 | 2014-01-13 | 2014-12-31 | 3 美元。 |
1084 | 231 | 2014-03-21 | 2014-06-05 | 3 美元 |
1086 | 235 | 2014-06-21 | 2014-09-09 | 4 美元 |
现在我想要基于 2014 年每个月的总收入的前 3 个包的结果。注意:例如包 231 的收入应该计算为 1 月的 18 天 * 3 美元 + 2 月的 28 天 * 3 美元 + ... 。 等等。对于第二行,计算将与第一行相同(3 月的 9 天 * 3 美元 + 4 月的 30 天 * 3 美元 ....)结果包应根据月份分组并根据总收入显示排名。
样本结果:
月 | Package_id | 收入 | 秩 |
---|---|---|---|
简 | 231. | 69499 | 1. |
简。 | 235. | 34345。 | 2. |
简。 | 238. | 23455。 | 3. |
二月 | 231. | 89274 | 1. |
我写了一个查询来过滤日期,以便我在 2014 年全年获得活跃订阅者(因为最初有来自不同年份的值),它显示了问题中的第一个表,但我不确定如何打破月份和之后的几天。
select subscriber_id, package_id, package_start_date, package_end_date
from (
select subscriber_id, package_id
, case when year(package_start_date) < '2014' then package_start_date = '01-Jan-2014' else package_start_date end as package_start_date
, case when year(package_start_date) > '2014' then package_end_date = '31-Dec-2014' else package_start_date end as package_end_date
, price_per_day
from subscription
) a
where year(package_start_date) = '2014' and year(package_end_date) = '2014'
请不要强调语法 - 我只是想了解 SQL 中的逻辑方法。
解决方案
假设您有一个表,该表是名为 d 的列中唯一日期的列表,并且该表称为 d
然后做起来相对微不足道
SELECT *
FROM t
INNER JOIN d on d.d >= t.package_start_date AND d.d < t.package_end_date
假设您将 1 月 1 日的开始日期和 1 月 2 日的结束日期分类为 1 天。如果你是两个,使用 <=
这将导致您的包裹行乘以天数,因此 1 月 1 日和 1 月 11 日的开始和结束天数意味着该行重复 10 次。每一行的 dd 日期都不同,您可以从 dd 中提取月份,然后对其进行分组,以便为您提供每个包裹每个月的总计
假设您已将上面的查询 CTEd 为 x,就像
SELECT DATEPART(month, x.dd), --the d.d date
package_id,
SUM(revenue)
FROM x
GROUP BY DATEPART(month, x.dd), package_id
因为 T 中的行在连接到 d 时会通过笛卡尔爆炸重复,因此您可以安全地对它们进行分组或聚合,以使它们恢复为每个包每月的单个值。如果您有超过一年的包裹,您还应该在日期部分年份分组,以避免混淆从例如 2020 年 1 月到 2021 年 2 月的包裹的月份(它们会停留两个 jan 和两个 feb)
然后你需要做的就是添加收入的排名,看起来它会在第一步进入,比如
RANK(DATEDIFF(DAY, start, end)*revenue) OVER(PARTITION BY package_id)
我想我理解正确,您在整个期间而不是按月对总收入进行排名。. 也请查看排名和密集排名之间的差异,因为您可能想要密集排名
推荐阅读
- android - 找不到 ChangeText 类/符号
- javascript - 这段 javascript 代码有问题
- git - 为什么我在本地 VM 上登录时,在共享文件夹中会得到不同的 git 状态?
- vue.js - Vuex 调度动作数据未定义
- javascript - 哪个更快:array[i] + n vs array[i+1]
- python - 对于 Solace PubSub+,“MESSAGE_SPOOL_DATA_NOT_AVAILABLE”是什么意思?
- python - 从 Pandas DataFrame 创建嵌套 JSON,将分组行作为最深嵌套内的属性
- python - 将 Python2 文件派生类移植到 Python 3
- javascript - JavaScript中的等号?
- python - Gensim LSI 方法 show_topics 返回的概率为什么是负数?