A B C
0 10062-35551-49007-45097 8/31/2014 0:00 233
1 10062-35551-49007-45097 10/31/2014 0:00 14
2 10062-35551-49007-45097 12/31/2014 0:00 22
我希望输出,因为B和C日期范围之间的所有月份都应在该日期范围内重复,例如:
A B C
0 10062-35551-49007-45097 8/31/2014 0:00 233
1 10062-35551-49007-45097 9/30/2014 0:00 233
2 10062-35551-49007-45097 10/31/2014 0:00 14
3 10062-35551-49007-45097 11/30/2014 0:00 14
4 10062-35551-49007-45097 12/31/2014 0:00 22
解决此问题的一种典型方法是首先创建一个参考表来保存月末日期列表。尽管开始时似乎需要付出额外的努力,但它的优点是使查询的编写更加简单(并且在很大程度上与RDBMS无关)。
假设我们创建表格all_dates
并存储2014年的所有月末日期:
create table all_dates (dt date not null primary key);
insert into all_dates values('2014-01-31');
insert into all_dates values('2014-02-28');
insert into all_dates values('2014-03-31');
insert into all_dates values('2014-04-30');
insert into all_dates values('2014-05-31');
insert into all_dates values('2014-06-30');
insert into all_dates values('2014-07-31');
insert into all_dates values('2014-08-31');
insert into all_dates values('2014-09-30');
insert into all_dates values('2014-10-31');
insert into all_dates values('2014-11-30');
insert into all_dates values('2014-12-31');
现在我们可以编写一个查询:
B
原始表格栏中的最小值和最大值选择相关的日期范围NOT EXISTS
条件将每个月末日期连接到原始表中的相关记录SQL:
SELECT t.A, d.dt B, t.C
FROM
all_dates d
INNER JOIN (
SELECT MIN(B) minb, MAX(B) maxb FROM mytable
) trange
ON d.dt >= trange.minb AND d.dt <= trange.maxb
INNER JOIN mytable t
ON t.B <= d.dt
AND NOT EXISTS (
SELECT 1
FROM mytable t1
WHERE t1.B <= d.dt AND t1.B > t.B
)
这个关于db-fiddle的演示以及您的示例数据返回:
| A | B | C |
| ----------------------- | ----------- | --- |
| 10062-35551-49007-45097 | 2014-08-31 | 233 |
| 10062-35551-49007-45097 | 2014-09-30 | 233 |
| 10062-35551-49007-45097 | 2014-10-31 | 14 |
| 10062-35551-49007-45097 | 2014-11-30 | 14 |
| 10062-35551-49007-45097 | 2014-12-31 | 22 |
PS:由于您没有说明要使用哪个RDBMS,因此我选择了MySQL;您可能需要all_tables
根据实际用例调整用于创建参考表的代码(但最终查询很可能保持不变)。
奖励:这是一个查询,可以正确处理column中存在多个不同值的用例A
:
SELECT t.A, d.dt B, t.C
FROM
all_dates d
INNER JOIN (
SELECT A, MIN(B) minb, MAX(B) maxb
FROM mytable
GROUP BY A
) trange
ON d.dt >= trange.minb AND d.dt <= trange.maxb
INNER JOIN mytable t
ON trange.A = t.A
AND t.B <= d.dt
AND NOT EXISTS (
SELECT 1
FROM mytable t1
WHERE
t1.A = t.A
AND t1.B <= d.dt
AND t1.B > t.B
)
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句