【问题标题】:Count if date in date column is between start and end date [ Oracle SQL ]计算日期列中的日期是否介于开始日期和结束日期之间 [Oracle SQL]
【发布时间】:2016-01-04 12:09:53
【问题描述】:

这是我的第一篇文章,所以我希望我已经正确地发布了这篇文章。

我的问题:

我想统计过去 30 天每天的活跃客户数量。

到目前为止我所拥有的:

在我今天要打印的第一列中,以及过去 29 天。我已经这样做了

select distinct trunc(sysdate-dayincrement, 'DD') AS DATES
from   (
  select level as dayincrement
  from   dual
  connect by level <= 30
)

我在 stackoverflow 上找到了它,它运行良好。我什至可以延长返回前的天数。 365 天。完美!

我也有一张这样的表

|Cust# | Start date | End date  |
| 1000 | 01.01.2015 | 31.12.2015|
| 1001 | 02.01.2015 | 31.12.2016|
| 1002 | 02.01.2015 | 31.03.2015|
| 1003 | 03.01.2015 | 31.08.2015|

这就是我觉得问题开始的地方

我想得到这个结果:

| Dates    | # of cust |
|04.01.2015|     4     |
|03.01.2015|     4     |
|02.01.2015|     3     |
|01.01.2015|     1     |

这里的查询将计为 1,如果:

  • 开始日期
  • 结束日期 >= DATES

否则计数为 0。

我只是不知道如何构造查询。

我试过了,但是没用。

count(
  IF ENDDATE <= DATES THEN
    IF STARTDATE >= DATES THEN 1 ELSE 0 END IF
  ELSE
    0
  END IF
) AS CUST

有什么想法吗?

【问题讨论】:

  • 您可能需要对日期的计数和按日期分组。不是我的电脑,否则我会为你写一个正确的答案。
  • 感谢您的帮助! :) 我认为您对 SUM 的看法是正确的,当然对 GROUP BY 也是如此。但是,我收到一条错误消息。 ORA-00923(错位 FROM)。我认为这个来自客户表,它是我从数据库创建的“混合表”。

标签: sql oracle date count


【解决方案1】:

以下会产生您正在寻找的结果。我已将日期生成器更改为从 04-JAN-2015 开始,而不是 SYSDATE(当然是在 2016 年),并使用 LEVEL-1包括“当前”日期:

WITH CUSTS AS (SELECT 1000 AS CUST_NO, TO_DATE('01-JAN-2015', 'DD-MON-YYYY') AS START_DATE, TO_DATE('31-DEC-2015', 'DD-MON-YYYY') AS END_DATE FROM DUAL UNION ALL
               SELECT 1001 AS CUST_NO, TO_DATE('02-JAN-2015', 'DD-MON-YYYY') AS START_DATE, TO_DATE('31-DEC-2016', 'DD-MON-YYYY') AS END_DATE FROM DUAL UNION ALL
               SELECT 1002 AS CUST_NO, TO_DATE('02-JAN-2015', 'DD-MON-YYYY') AS START_DATE, TO_DATE('31-MAR-2015', 'DD-MON-YYYY') AS END_DATE FROM DUAL UNION ALL
               SELECT 1003 AS CUST_NO, TO_DATE('03-JAN-2015', 'DD-MON-YYYY') AS START_DATE, TO_DATE('31-AUG-2015', 'DD-MON-YYYY') AS END_DATE FROM DUAL ),
     DATES AS (SELECT DISTINCT TRUNC(TO_DATE('04-JAN-2015', 'DD-MON-YYYY') - DAYINCREMENT, 'DD') AS DT
                FROM (SELECT LEVEL-1 AS DAYINCREMENT
                        FROM DUAL
                        CONNECT BY LEVEL <= 30))
SELECT d.DT, COUNT(*)
  FROM CUSTS c
  CROSS JOIN DATES d
  WHERE d.DT BETWEEN c.START_DATE AND c.END_DATE
  GROUP BY d.DT
  ORDER BY DT DESC

祝你好运。

【讨论】:

  • 哦。该死。那个有效! :D 非常感谢! :)
【解决方案2】:

您可以编写一个与 IF-ELSE 构造等效的 CASE 表达式。

例如,

SQL> SELECT COUNT(
  2    CASE
  3      WHEN hiredate <= sysdate
  4      THEN 1
  5      ELSE 0
  6    END ) AS CUST
  7  FROM emp;

      CUST
----------
        14

SQL>

但是,查看您想要的输出,您似乎只需要使用 COUNTGROUP BY日期条件应该在过滤谓词中。

例如,

SELECT dates, COUNT(*) 
FROM   table_name
WHERE  dates BETWEEN start_date AND end_date
GROUP BY dates;

【讨论】:

  • 感谢您的帮助! :) 但是,这不会保留左栏中的日期吗?我需要这个,因为我想获得一个时间序列,以便稍后用于绘制客户数量的图表。
  • @PKH 这是一个小错字。只需在选择中输入dates
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-22
  • 2015-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多