Sql 如何计算以日期值表示的间隔中存在的季度数?

Sql 如何计算以日期值表示的间隔中存在的季度数?,sql,database,Sql,Database,我有以下数据库表,我使用Oracle数据库: 计算中有错误吗?有可能解决这个问题吗?如果我说的没错,您需要的是一个季度列表,您的数据当前与之重叠 在我看来,最简单的方法是使用日历表。填充您感兴趣的所有日期。数字表或日历表有很多用途,我将留给您单独研究 对于这个问题,一个简单的例子如下: CREATE TABLE calendar_quarters ( interval_start DATE, interval_cease DATE ); INSERT INTO ca

我有以下数据库表,我使用Oracle数据库:


计算中有错误吗?有可能解决这个问题吗?

如果我说的没错,您需要的是一个季度列表,您的数据当前与之重叠

在我看来,最简单的方法是使用日历表。填充您感兴趣的所有日期。数字表或日历表有很多用途,我将留给您单独研究

对于这个问题,一个简单的例子如下:

CREATE TABLE calendar_quarters (
    interval_start    DATE,
    interval_cease    DATE
);

INSERT INTO calendar_quarters VALUES ('2018-01-01', '2018-04-01');
INSERT INTO calendar_quarters VALUES ('2018-04-01', '2018-07-01');
INSERT INTO calendar_quarters VALUES ('2018-07-01', '2018-10-01');
INSERT INTO calendar_quarters VALUES ('2018-10-01', '2019-01-01');
INSERT INTO calendar_quarters VALUES ('2019-01-01', '2019-04-01');
INSERT INTO calendar_quarters VALUES ('2019-04-01', '2019-07-01');
INSERT INTO calendar_quarters VALUES ('2019-07-01', '2019-10-01');
INSERT INTO calendar_quarters VALUES ('2019-10-01', '2020-01-01');
INSERT INTO calendar_quarters VALUES ('2020-01-01', '2020-04-01');
INSERT INTO calendar_quarters VALUES ('2020-04-01', '2020-07-01');
INSERT INTO calendar_quarters VALUES ('2020-07-01', '2020-10-01');
INSERT INTO calendar_quarters VALUES ('2020-10-01', '2021-01-01');
一旦你有了间隔图,你只需要看看哪些间隔与你的数据重叠

SELECT
  calendar_quarters.interval_start
FROM
  your_table
INNER JOIN
  calendar_quarters
    ON  your_table.BEGINN_DATE < calendar_quarters.interval_cease
    AND your_table.END_DATE    > calendar_quarters.interval_start
GROUP BY
  calendar_quarters.interval_start
还要注意,一个间隔的结束日期与下一个间隔的开始日期相同。这使用了包含性开始、独占性结束,这是一种标准方法,并且使日期数学/操作的许多方面更容易在web上搜索更多信息


这意味着您可能需要在结束日期值中添加一天,在查询中添加一天,或者使用>=和如果我是正确的,您需要的是当前数据重叠的季度列表

在我看来,最简单的方法是使用日历表。填充您感兴趣的所有日期。数字表或日历表有很多用途,我将留给您单独研究

对于这个问题,一个简单的例子如下:

CREATE TABLE calendar_quarters (
    interval_start    DATE,
    interval_cease    DATE
);

INSERT INTO calendar_quarters VALUES ('2018-01-01', '2018-04-01');
INSERT INTO calendar_quarters VALUES ('2018-04-01', '2018-07-01');
INSERT INTO calendar_quarters VALUES ('2018-07-01', '2018-10-01');
INSERT INTO calendar_quarters VALUES ('2018-10-01', '2019-01-01');
INSERT INTO calendar_quarters VALUES ('2019-01-01', '2019-04-01');
INSERT INTO calendar_quarters VALUES ('2019-04-01', '2019-07-01');
INSERT INTO calendar_quarters VALUES ('2019-07-01', '2019-10-01');
INSERT INTO calendar_quarters VALUES ('2019-10-01', '2020-01-01');
INSERT INTO calendar_quarters VALUES ('2020-01-01', '2020-04-01');
INSERT INTO calendar_quarters VALUES ('2020-04-01', '2020-07-01');
INSERT INTO calendar_quarters VALUES ('2020-07-01', '2020-10-01');
INSERT INTO calendar_quarters VALUES ('2020-10-01', '2021-01-01');
一旦你有了间隔图,你只需要看看哪些间隔与你的数据重叠

SELECT
  calendar_quarters.interval_start
FROM
  your_table
INNER JOIN
  calendar_quarters
    ON  your_table.BEGINN_DATE < calendar_quarters.interval_cease
    AND your_table.END_DATE    > calendar_quarters.interval_start
GROUP BY
  calendar_quarters.interval_start
还要注意,一个间隔的结束日期与下一个间隔的开始日期相同。这使用了包含性开始、独占性结束,这是一种标准方法,并且使日期数学/操作的许多方面更容易在web上搜索更多信息


这意味着您可能希望在结束日期值上添加一天,在查询中为它们添加一天,或者使用>=和如何?第1-5行表示您已经拥有的样本数据,所以您需要的查询从第7行开始

如果开始日期不属于某个季度开始的月份,则将其截断为季度第8行 以前的解决方案将其截断为mm,这是该月的第一天 如果没有结束日期,请将nvl函数与sysdate行12一起使用
注意第7行,它使用distinct。如果删除它,将得到约300行,其中许多是重复的。我最初发布的代码处理了这个问题,并且比distinct处理得更好。对于小数据集,您不会注意到差异,但如果您必须处理大量数据,您肯定会注意到差异。

这如何?第1-5行表示您已经拥有的样本数据,所以您需要的查询从第7行开始

如果开始日期不属于某个季度开始的月份,则将其截断为季度第8行 以前的解决方案将其截断为mm,这是该月的第一天 如果没有结束日期,请将nvl函数与sysdate行12一起使用
注意第7行,它使用distinct。如果删除它,将得到约300行,其中许多是重复的。我最初发布的代码处理了这个问题,并且比distinct处理得更好。对于小数据集,您不会注意到差异,但如果必须处理大量数据,您肯定会注意到差异。

不客气。如果有空值,修改第17行并使用nvlend\u date、sysdate.Ooops!抱歉,这是第11行。整个9-14部分用于避免在源表本身上使用分层查询时出现重复。sys.odcinumberlist是Oracle内置的数字数组;在该查询中,它包含该分层查询生成的所有级别,然后将这些级别转换为一个数组-sys.odcinumberlist.Yes;这是因为我假设所有的开始日期都属于某个季度开始的月份,因为这是您最初的样本数据所建议的。如果不是的话——就像118一样——事情会变得更复杂。我修改了代码,使它现在能够反映您所评论的两个更改。请看一看,不客气。如果有空值,修改第17行并使用nvlend\u date、sysdate.Ooops!抱歉,这是第11行。整个9-14部分用于避免在源表本身上使用分层查询时出现重复。sys.odcinumberlist是Oracle内置的数字数组;在该查询中,它包含该分层查询生成的所有级别,然后将这些级别转换为一个数组-sys.odcinumberlist.Yes;这是因为我假设所有的开始日期都属于某个季度开始的月份,因为这是您最初的样本数据所建议的。如果不是的话——就像118一样——事情会变得更复杂。我修改了代码,使它现在能够反映您所评论的两个更改。请看一看。