如何减去基于不同状态的两列合一 table 的聚合计数?
How do I subtract aggregated counts based on different states two columns in one table?
使用 MariaDB,我试图获取每个月创建的项目减去当月删除的项目的月度总数。如果没有项目被删除,总数应该只是当月创建的项目数。如果删除的项目多于创建的项目,则总数应为负数。
table 有一个永远不会为空的 created_at
列和一个 deleted_at
列,该列在项目被 'deleted'
后设置
为了说明,(简化的)模式是这样的:
TABLE 项:
+----------------------------------------------------------------------------+
| idItem | created_at | deleted_at |
+----------------------------------------------------------------------------+
| 1 | 2020-03-20T04:28:41.000+00:00 | 2021-07-27T02:36:05.000+00:00 |
| 2 | 2020-03-20T04:28:41.000+00:00 | 2021-07-27T02:36:05.000+00:00 |
| 3 | 2021-03-02T21:39:10.000+00:00 | ∅ |
| 4 | 2021-03-05T21:13:13.000+00:00 | ∅ |
| 5 | 2021-06-08T13:49:11.000+00:00 | 2021-07-27T02:36:05.000+00:00 |
| 6 | 2021-07-13T02:36:05.000+00:00 | ∅
| 7 | 2021-09-17T21:12:13.000+00:00 | ∅ |
+----------------------------------------------------------------------------+
我需要的信息是没有被删除的月总计,像这样:
+-----------------------------------+
| total_existing | during_month |
+-----------------------------------+
| 2 | 2020-03 | -- two were added
+-----------------------------------+
| 4 | 2021-03 | -- another two were created
+-----------------------------------+
| 5 | 2021-06 | -- another was added
+-----------------------------------+
| 3 | 2021-07 | -- three deleted, one added
+-----------------------------------+
| 4 | 2021-09 | -- one added
+-----------------------------------+
最终,我需要显示每个月的总数。
我已经试过了,但这是不对的。
SELECT
count(created.idItem) AS monthly_created_count,
count(deleted.idItem) AS monthly_deleted_count,
count(created.idItem) - count(deleted.idItem) as total,
DATE_FORMAT(created.created_at, '%Y-%m') as created_month ,
DATE_FORMAT(deleted.deleted_at, '%Y-%m') as deleted_month
FROM
Item created
LEFT JOIN
Item deleted
ON
DATE_FORMAT(deleted.deleted_at, '%Y-%m') = DATE_FORMAT(created.created_at, '%Y-%m')
GROUP BY DATE_FORMAT(created.created_at, '%Y-%m'), DATE_FORMAT(deleted.deleted_at, '%Y-%m')
我一直认为我很接近,但是当我们查看设置了 deleted_at 日期的行时,很明显我错了。
如果您要查找累计行数 created/deleted,一种方法是计算 month/year 分别 创建和删除的记录数.然后将计数与 UNION ALL 结合在一起并计算总和:
SELECT t.YearMonth
, SUM(t.TotalCreated) - SUM(t.TotalDeleted) AS TotalExisting
FROM (
SELECT DATE_FORMAT(created_at, '%Y-%m') AS YearMonth
, COUNT(*) AS TotalCreated
, 0 AS TotalDeleted
FROM Item
GROUP BY DATE_FORMAT(created_at, '%Y-%m')
UNION ALL
SELECT DATE_FORMAT(deleted_at, '%Y-%m') AS YearMonth
, 0 AS TotalCreated
, COUNT(*) AS TotalDeleted
FROM Item
WHERE deleted_at IS NOT NULL
GROUP BY DATE_FORMAT(deleted_at, '%Y-%m')
) t
GROUP BY t.YearMonth
ORDER BY t.YearMonth
结果:
YearMonth | TotalExisting
:-------- | ------------:
2020-03 | 2
2021-03 | 2
2021-06 | 1
2021-07 | -2
2021-09 | 1
然后将这些语句包装在 CTE 中并使用 Window Function 计算滚动总数:
另见 db<>fiddle
WITH cte AS (
SELECT t.YearMonth
, SUM(t.TotalCreated) - SUM(t.TotalDeleted) AS TotalExisting
FROM (
SELECT DATE_FORMAT(created_at, '%Y-%m') AS YearMonth
, COUNT(*) AS TotalCreated
, 0 AS TotalDeleted
FROM Item
GROUP BY DATE_FORMAT(created_at, '%Y-%m')
UNION ALL
SELECT DATE_FORMAT(deleted_at, '%Y-%m') AS YearMonth
, 0 AS TotalCreated
, COUNT(*) AS TotalDeleted
FROM Item
WHERE deleted_at IS NOT NULL
GROUP BY DATE_FORMAT(deleted_at, '%Y-%m')
) t
GROUP BY t.YearMonth
ORDER BY t.YearMonth
)
SELECT YearMonth, SUM(TotalExisting) OVER (ORDER BY YearMonth) AS TotalExisting
FROM cte;
最终结果:
YearMonth | TotalExisting
:-------- | ------------:
2020-03 | 2
2021-03 | 4
2021-06 | 5
2021-07 | 3
2021-09 | 4
使用 MariaDB,我试图获取每个月创建的项目减去当月删除的项目的月度总数。如果没有项目被删除,总数应该只是当月创建的项目数。如果删除的项目多于创建的项目,则总数应为负数。
table 有一个永远不会为空的 created_at
列和一个 deleted_at
列,该列在项目被 'deleted'
为了说明,(简化的)模式是这样的: TABLE 项:
+----------------------------------------------------------------------------+
| idItem | created_at | deleted_at |
+----------------------------------------------------------------------------+
| 1 | 2020-03-20T04:28:41.000+00:00 | 2021-07-27T02:36:05.000+00:00 |
| 2 | 2020-03-20T04:28:41.000+00:00 | 2021-07-27T02:36:05.000+00:00 |
| 3 | 2021-03-02T21:39:10.000+00:00 | ∅ |
| 4 | 2021-03-05T21:13:13.000+00:00 | ∅ |
| 5 | 2021-06-08T13:49:11.000+00:00 | 2021-07-27T02:36:05.000+00:00 |
| 6 | 2021-07-13T02:36:05.000+00:00 | ∅
| 7 | 2021-09-17T21:12:13.000+00:00 | ∅ |
+----------------------------------------------------------------------------+
我需要的信息是没有被删除的月总计,像这样:
+-----------------------------------+
| total_existing | during_month |
+-----------------------------------+
| 2 | 2020-03 | -- two were added
+-----------------------------------+
| 4 | 2021-03 | -- another two were created
+-----------------------------------+
| 5 | 2021-06 | -- another was added
+-----------------------------------+
| 3 | 2021-07 | -- three deleted, one added
+-----------------------------------+
| 4 | 2021-09 | -- one added
+-----------------------------------+
最终,我需要显示每个月的总数。 我已经试过了,但这是不对的。
SELECT
count(created.idItem) AS monthly_created_count,
count(deleted.idItem) AS monthly_deleted_count,
count(created.idItem) - count(deleted.idItem) as total,
DATE_FORMAT(created.created_at, '%Y-%m') as created_month ,
DATE_FORMAT(deleted.deleted_at, '%Y-%m') as deleted_month
FROM
Item created
LEFT JOIN
Item deleted
ON
DATE_FORMAT(deleted.deleted_at, '%Y-%m') = DATE_FORMAT(created.created_at, '%Y-%m')
GROUP BY DATE_FORMAT(created.created_at, '%Y-%m'), DATE_FORMAT(deleted.deleted_at, '%Y-%m')
我一直认为我很接近,但是当我们查看设置了 deleted_at 日期的行时,很明显我错了。
如果您要查找累计行数 created/deleted,一种方法是计算 month/year 分别 创建和删除的记录数.然后将计数与 UNION ALL 结合在一起并计算总和:
SELECT t.YearMonth
, SUM(t.TotalCreated) - SUM(t.TotalDeleted) AS TotalExisting
FROM (
SELECT DATE_FORMAT(created_at, '%Y-%m') AS YearMonth
, COUNT(*) AS TotalCreated
, 0 AS TotalDeleted
FROM Item
GROUP BY DATE_FORMAT(created_at, '%Y-%m')
UNION ALL
SELECT DATE_FORMAT(deleted_at, '%Y-%m') AS YearMonth
, 0 AS TotalCreated
, COUNT(*) AS TotalDeleted
FROM Item
WHERE deleted_at IS NOT NULL
GROUP BY DATE_FORMAT(deleted_at, '%Y-%m')
) t
GROUP BY t.YearMonth
ORDER BY t.YearMonth
结果:
YearMonth | TotalExisting
:-------- | ------------:
2020-03 | 2
2021-03 | 2
2021-06 | 1
2021-07 | -2
2021-09 | 1
然后将这些语句包装在 CTE 中并使用 Window Function 计算滚动总数:
另见 db<>fiddle
WITH cte AS (
SELECT t.YearMonth
, SUM(t.TotalCreated) - SUM(t.TotalDeleted) AS TotalExisting
FROM (
SELECT DATE_FORMAT(created_at, '%Y-%m') AS YearMonth
, COUNT(*) AS TotalCreated
, 0 AS TotalDeleted
FROM Item
GROUP BY DATE_FORMAT(created_at, '%Y-%m')
UNION ALL
SELECT DATE_FORMAT(deleted_at, '%Y-%m') AS YearMonth
, 0 AS TotalCreated
, COUNT(*) AS TotalDeleted
FROM Item
WHERE deleted_at IS NOT NULL
GROUP BY DATE_FORMAT(deleted_at, '%Y-%m')
) t
GROUP BY t.YearMonth
ORDER BY t.YearMonth
)
SELECT YearMonth, SUM(TotalExisting) OVER (ORDER BY YearMonth) AS TotalExisting
FROM cte;
最终结果:
YearMonth | TotalExisting
:-------- | ------------:
2020-03 | 2
2021-03 | 4
2021-06 | 5
2021-07 | 3
2021-09 | 4