按月检索未完成的记录查询

huangapple go评论79阅读模式
英文:

Query to retrieve incomplete records by month

问题

在给定的Oracle数据库示例数据中:

| ID    | Step | StartDate | CompDate  |
| ----- | ---- | --------  | --------- |
| 98775 | 4.24 | 28-Jun-23 |           |
| 98776 | 4.31 | 28-Jun-23 | 5-Jul-23  |
| 98777 | 4.24 | 28-Jun-23 |           |
| 98845 | 4.31 | 26-Jul-23 | 2-Aug-23  |
| 98846 | 4.31 | 27-Jul-23 | 27-Jul-23 |
| 98847 | 4.24 | 31-Jul-23 |           |
| 98848 | 4.31 | 31-Jul-23 | 2-Aug-23  |
| 98853 | 4.31 | 3-Aug-23  | 3-Aug-23  |
| 98854 | 4.24 | 3-Aug-23  |           |
| 98855 | 4.23 | 3-Aug-23  |           |

您需要一个查询,以按月返回剩余记录。查询应返回以下值:

为了解释我需要什么,在上面的示例数据中,6月期间创建了3条记录。在这3条记录中,没有一条在6月份完成,所以6月份的剩余记录数为3。在7月份,创建了4条记录,1条来自6月,1条来自7月完成。这意味着在7月底,从6月和7月创建的记录中仍有5条未完成。8月份,创建了3条记录,2条来自7月完成,1条来自8月完成。8月份的剩余计数为5。我需要每个月尚未完成的任务的运行总数。

|ColumnName|Records|
|----------|-------|
|2023-06|3|
|2023-07|5|
|2023-08|5|

我已经尝试过这个查询,但计数不正确:

WITH record_creations AS (
    SELECT
        TO_CHAR(startdate, 'YYYY-MM') AS month,
        COUNT(id) AS created_records
    FROM
        table1
    WHERE id in (98775,98776,98777,98845,98846,98847,98848,98853,98854,98855)
    GROUP BY
        TO_CHAR(startdate, 'YYYY-MM')
),
records_incomplete AS (
    SELECT
        TO_CHAR(compdate, 'YYYY-MM') AS month,
        COUNT(id) AS remaining_records
    FROM
        table1
    WHERE
        compdate IS NULL
        and id in (98775,98776,98777,98845,98846,98847,98848,98853,98854,98855)
    GROUP BY
        TO_CHAR(compdate, 'YYYY-MM')
)
SELECT
    NVL(c.month, i.month) AS ColumnName,
    NVL(created_records, 0) - NVL(remaining_records, 0) AS records
FROM
    record_creations c
    FULL OUTER JOIN records_incomplete i ON c.month = i.month
ORDER BY
    NVL(c.month, i.month)

这个查询返回以下结果:

|ColumnName|Records|
|----------|-------|
|2023-06|3|
|2023-07|4|
|2023-08|3|

如果您想要修复这个查询以获得正确的计数,请让我知道,我可以提供更多帮助。

英文:

Given this sample data in an Oracle database:

ID Step StartDate CompDate
98775 4.24 28-Jun-23
98776 4.31 28-Jun-23 5-Jul-23
98777 4.24 28-Jun-23
98845 4.31 26-Jul-23 2-Aug-23
98846 4.31 27-Jul-23 27-Jul-23
98847 4.24 31-Jul-23
98848 4.31 31-Jul-23 2-Aug-23
98853 4.31 3-Aug-23 3-Aug-23
98854 4.24 3-Aug-23
98855 4.23 3-Aug-23

I need a query that will return the remaining records by month. The query should return values like this:

To explain what I need, in the sample data above, 3 records were created during June. Of those 3 records, 0 were completed during June, so the remaining records count for June is 3. In July, 4 records were created, 1 from June and 1 from July were completed. This means that, at the end of July, 5 records remained from the ones created during June and July. In August, 3 records were created, 2 from July were completed, and 1 from August was completed. The remaining count for August is 5. I need a running total of tasks not yet completed for each month.

ColumnName Records
2023-06 3
2023-07 5
2023-08 5

I've tried this query but the counts are off:

WITH record_creations AS (
    SELECT
        TO_CHAR(startdate, 'YYYY-MM') AS month,
        COUNT(id) AS created_records
    FROM
        table1
    WHERE id in (98775,98776,98777,98845,98846,98847,98848,98853,98854,98855)
    GROUP BY
        TO_CHAR(startdate, 'YYYY-MM')
),
records_incomplete AS (
    SELECT
        TO_CHAR(compdate, 'YYYY-MM') AS month,
        COUNT(id) AS remaining_records
    FROM
        table1
    WHERE
        compdate IS  NULL
        and id in (98775,98776,98777,98845,98846,98847,98848,98853,98854,98855)
    GROUP BY
        TO_CHAR(compdate, 'YYYY-MM')
)
SELECT
    NVL(c.month, i.month) AS ColumnName,
    NVL(created_records, 0) - NVL(remaining_records, 0) AS records
FROM
    record_creations c
    FULL OUTER JOIN records_incomplete i ON c.month = i.month
ORDER BY
    NVL(c.month, i.month)

This query returns this:

ColumnName Records
2023-06 3
2023-07 4
2023-08 3

答案1

得分: 0

你可以使用`UNPIVOT`操作来将日期进行转换,然后计算每个月开始的数量减去完成的数量的累积总数:

```sql
SELECT  DISTINCT
        TO_CHAR(dt, 'YYYY-MM') AS 月份,
        SUM(active) OVER (ORDER BY TO_CHAR(dt, 'YYYY-MM')) AS 未完成数量
FROM    (
  SELECT startdate, compdate
  FROM   table_name
)
UNPIVOT (dt FOR active IN (startdate AS 1, compdate AS -1))
ORDER BY 月份;

对于示例数据:

CREATE TABLE table_name (ID, Step, StartDate, CompDate) AS
SELECT 98775, 4.24, DATE '2023-06-28', NULL FROM DUAL UNION ALL
SELECT 98776, 4.31, DATE '2023-06-28', DATE '2023-07-05' FROM DUAL UNION ALL
SELECT 98777, 4.24, DATE '2023-06-28', NULL FROM DUAL UNION ALL
SELECT 98845, 4.31, DATE '2023-07-26', DATE '2023-08-02' FROM DUAL UNION ALL
SELECT 98846, 4.31, DATE '2023-07-27', DATE '2023-07-27' FROM DUAL UNION ALL
SELECT 98847, 4.24, DATE '2023-07-31', NULL FROM DUAL UNION ALL
SELECT 98848, 4.31, DATE '2023-07-31', DATE '2023-08-02' FROM DUAL UNION ALL
SELECT 98853, 4.31, DATE '2023-08-03', DATE '2023-08-03' FROM DUAL UNION ALL
SELECT 98854, 4.24, DATE '2023-08-03', NULL FROM DUAL UNION ALL
SELECT 98855, 4.23, DATE '2023-08-03', NULL FROM DUAL;

输出结果:

月份 未完成数量
2023-06 3
2023-07 5
2023-08 5

fiddle


<details>
<summary>英文:</summary>

You can `UNPIVOT` the dates and then calculate a running total of the number started minus the number completed for each month:

```lang-sql
SELECT  DISTINCT
        TO_CHAR(dt, &#39;YYYY-MM&#39;) AS month,
        SUM(active) OVER (ORDER BY TO_CHAR(dt, &#39;YYYY-MM&#39;)) AS outstanding
FROM    (
  SELECT startdate, compdate
  FROM   table_name
)
UNPIVOT (dt FOR active IN (startdate AS 1, compdate AS -1))
ORDER BY month;

Which, for the sample data:

CREATE TABLE table_name (ID, Step, StartDate, CompDate) AS
SELECT 98775, 4.24, DATE &#39;2023-06-28&#39;, NULL FROM DUAL UNION ALL
SELECT 98776, 4.31, DATE &#39;2023-06-28&#39;, DATE &#39;2023-07-05&#39; FROM DUAL UNION ALL
SELECT 98777, 4.24, DATE &#39;2023-06-28&#39;, NULL FROM DUAL UNION ALL
SELECT 98845, 4.31, DATE &#39;2023-07-26&#39;, DATE &#39;2023-08-02&#39; FROM DUAL UNION ALL
SELECT 98846, 4.31, DATE &#39;2023-07-27&#39;, DATE &#39;2023-07-27&#39; FROM DUAL UNION ALL
SELECT 98847, 4.24, DATE &#39;2023-07-31&#39;, NULL FROM DUAL UNION ALL
SELECT 98848, 4.31, DATE &#39;2023-07-31&#39;, DATE &#39;2023-08-02&#39; FROM DUAL UNION ALL
SELECT 98853, 4.31, DATE &#39;2023-08-03&#39;, DATE &#39;2023-08-03&#39; FROM DUAL UNION ALL
SELECT 98854, 4.24, DATE &#39;2023-08-03&#39;, NULL FROM DUAL UNION ALL
SELECT 98855, 4.23, DATE &#39;2023-08-03&#39;, NULL FROM DUAL;

Outputs:

MONTH OUTSTANDING
2023-06 3
2023-07 5
2023-08 5

fiddle

答案2

得分: 0

以下是翻译好的内容:

可以使用递归查询来生成所有的月份,然后计算在每个月底之前已经开始但尚未完成的项目数量:

```lang-sql
WITH months (month, endmonth) AS (
  SELECT MIN(TRUNC(startdate, 'MM')),
         MAX(TRUNC(compdate, 'MM'))
  FROM   table_name
UNION ALL
  SELECT ADD_MONTHS(month, 1),
         endmonth
  FROM   months
  WHERE  month < endmonth
)
SELECT TO_CHAR(month, 'YYYY-MM') AS month,
       ( SELECT COUNT(*)
         FROM   table_name
         WHERE  startdate <  ADD_MONTHS(m.month, 1)
         AND    (  compdate  >= ADD_MONTHS(m.month, 1)
                OR compdate IS NULL )
       ) AS outstanding
FROM   months m

对于样本数据:

CREATE TABLE table_name (ID, Step, StartDate, CompDate) AS
SELECT 98775, 4.24, DATE '2023-06-28', NULL FROM DUAL UNION ALL
SELECT 98776, 4.31, DATE '2023-06-28', DATE '2023-07-05' FROM DUAL UNION ALL
SELECT 98777, 4.24, DATE '2023-06-28', NULL FROM DUAL UNION ALL
SELECT 98845, 4.31, DATE '2023-07-26', DATE '2023-08-02' FROM DUAL UNION ALL
SELECT 98846, 4.31, DATE '2023-07-27', DATE '2023-07-27' FROM DUAL UNION ALL
SELECT 98847, 4.24, DATE '2023-07-31', NULL FROM DUAL UNION ALL
SELECT 98848, 4.31, DATE '2023-07-31', DATE '2023-08-02' FROM DUAL UNION ALL
SELECT 98853, 4.31, DATE '2023-08-03', DATE '2023-08-03' FROM DUAL UNION ALL
SELECT 98854, 4.24, DATE '2023-08-03', NULL FROM DUAL UNION ALL
SELECT 98855, 4.23, DATE '2023-08-03', NULL FROM DUAL;

输出结果:

月份 OUTSTANDING
2023-06 3
2023-07 5
2023-08 5

[fiddle](https://dbfiddle.uk/S-lP7gj6)

<details>
<summary>英文:</summary>

You can use a recursive query to generate all the months and then count how many projects have started before the end of each month but have not yet finished:

```lang-sql
WITH months (month, endmonth) AS (
  SELECT MIN(TRUNC(startdate, &#39;MM&#39;)),
         MAX(TRUNC(compdate, &#39;MM&#39;))
  FROM   table_name
UNION ALL
  SELECT ADD_MONTHS(month, 1),
         endmonth
  FROM   months
  WHERE  month &lt; endmonth
)
SELECT TO_CHAR(month, &#39;YYYY-MM&#39;) AS month,
       ( SELECT COUNT(*)
         FROM   table_name
         WHERE  startdate &lt;  ADD_MONTHS(m.month, 1)
         AND    (  compdate  &gt;= ADD_MONTHS(m.month, 1)
                OR compdate IS NULL )
       ) AS outstanding
FROM   months m

Which, for the sample data:

CREATE TABLE table_name (ID, Step, StartDate, CompDate) AS
SELECT 98775, 4.24, DATE &#39;2023-06-28&#39;, NULL FROM DUAL UNION ALL
SELECT 98776, 4.31, DATE &#39;2023-06-28&#39;, DATE &#39;2023-07-05&#39; FROM DUAL UNION ALL
SELECT 98777, 4.24, DATE &#39;2023-06-28&#39;, NULL FROM DUAL UNION ALL
SELECT 98845, 4.31, DATE &#39;2023-07-26&#39;, DATE &#39;2023-08-02&#39; FROM DUAL UNION ALL
SELECT 98846, 4.31, DATE &#39;2023-07-27&#39;, DATE &#39;2023-07-27&#39; FROM DUAL UNION ALL
SELECT 98847, 4.24, DATE &#39;2023-07-31&#39;, NULL FROM DUAL UNION ALL
SELECT 98848, 4.31, DATE &#39;2023-07-31&#39;, DATE &#39;2023-08-02&#39; FROM DUAL UNION ALL
SELECT 98853, 4.31, DATE &#39;2023-08-03&#39;, DATE &#39;2023-08-03&#39; FROM DUAL UNION ALL
SELECT 98854, 4.24, DATE &#39;2023-08-03&#39;, NULL FROM DUAL UNION ALL
SELECT 98855, 4.23, DATE &#39;2023-08-03&#39;, NULL FROM DUAL;

Outputs:

MONTH OUTSTANDING
2023-06 3
2023-07 5
2023-08 5

fiddle

huangapple
  • 本文由 发表于 2023年8月4日 02:41:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/76830845.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定