简体   繁体   English

从两个日期获取 COUNT 个 DISTINCT 月

[英]Get COUNT of DISTINCT Months From Two Dates

I am trying to get count of distinct months between two dates.我正在尝试计算两个日期之间的不同月份。 However, I am getting a missing right parenthesis error.但是,我得到一个缺少右括号的错误。 As with many of us I like using dual table on the fly.和我们中的许多人一样,我喜欢即时使用双桌。

Here is the query.这是查询。 Can you please advise what I am doing wrong?你能告诉我我做错了什么吗?

SELECT 
COUNT(DISTINCT(TRUNC BETWEEN TO_DATE('2019-08-01','YYYY-MM-DD') AND TO_DATE('2020-07-07','YYYY-MM-DD'),'MM'))
FROM dual

Your approach is incorrect and It is better to use MONTHS_BETWEEN as it takes care of everything ie different number of days in the month and etc.您的方法不正确,最好使用MONTHS_BETWEEN ,因为它会处理所有事情,即一个月中不同的天数等。

You can use MONTHS_BETWEEN as follows:您可以按如下方式使用MONTHS_BETWEEN

SELECT 
MONTHS_BETWEEN (TO_DATE('2020-07-07','YYYY-MM-DD'),TO_DATE('2019-08-01','YYYY-MM-DD'))
FROM dual

Counting isn't the right tool for this really;计数确实不是正确的工具。 your trunc() is missing its opening parenthesis, but BETWEEN is a condition not a function, so that is also wrong.您的trunc()缺少左括号,但BETWEEN不是 function 的条件,所以这也是错误的。

Oracle has the months_between() function to do this; Oracle 有months_between() function来执行此操作; it will give a fractional value, so you can use floor() to get the number of complete months, or ceil() to get the number of partial months:它将给出一个小数值,因此您可以使用floor()获取完整月数,或使用ceil()获取部分月数:

select
  months_between (date '2020-07-07', date '2019-08-01') as result1,
  floor(months_between (date '2020-07-07', date '2019-08-01')) as result2,
  ceil(months_between (date '2020-07-07', date '2019-08-01')) as result3
from dual;

   RESULT1    RESULT2    RESULT3
---------- ---------- ----------
11.1935484         11         12

If you wanted to list the months then you could use a hierarchcal query or recursive subquery factoring, eg:如果您想列出月份,则可以使用分层查询或递归子查询分解,例如:

with rcte (this_month, last_month) as (
  select trunc(date '2019-08-01', 'MM'), trunc(date '2020-07-07', 'MM')
  from dual
  union all
  select r.this_month + interval '1' month, r.last_month
  from rcte r
  where r.this_month < r.last_month
)
select this_month
from rcte
order by this_month;

THIS_MONTH
----------
2019-08-01
2019-09-01
2019-10-01
...
2020-06-01
2020-07-01

and count those instead:并计算那些:

with rcte (this_month, last_month) as (
  select trunc(date '2019-08-01', 'MM'), trunc(date '2020-07-07', 'MM')
  from dual
  union all
  select r.this_month + interval '1' month, r.last_month
  from rcte r
  where r.this_month < r.last_month
)
select count(this_month) as result
from rcte;

RESULT
------
    12

but that's more work than you need to do if you only want that number.但是,如果您只想要那个数字,这比您需要做的工作要多。

db<>fiddle db<>小提琴

months_between may not be solution for all scenarios; months_between 可能不是所有场景的解决方案; example:例子:

SELECT MONTHS_BETWEEN (TO_DATE('2021-12-20','YYYY-MM-DD'),TO_DATE('2022-01-05','YYYY-MM-DD')) FROM dual will result is 0.5 months; SELECT MONTHS_BETWEEN (TO_DATE('2021-12-20','YYYY-MM-DD'),TO_DATE('2022-01-05','YYYY-MM-DD')) 的结果是 0.5 个月; but actually both dec and jan are used in query and expected result may 2.但实际上 dec 和 jan 都用于查询,预期结果可能是 2。

So using above example of with function will provide correct result no matter.因此,使用上面的示例 function 无论如何都会提供正确的结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM