从交易表中选择行,如果缺少数据也返回 0 值

问题描述 投票:0回答:1

我使用 SQLite 开发了一个小应用程序,用于跟踪费用。在此应用程序中,我有下表:

--------------------------
date | expense | value
--------------------------
2024-01-01 | Food | 25.99
2024-01-19 | Food | 4.99
2024-01-01 | Apple | 9.99
2024-01-10 | Phone | 15.99
2024-03-10 | Food | 20.00
...

我过去使用过查询来获取按类型、月份和年份列出的所有费用的摘要,如下所示:

SELECT 
    expense, 
    sum(value) as balance, 
    strftime("%m", valuationdate) as month, strftime("%Y", valuationdate) as year
FROM Transactions
group by expense, month, year
order by expense, year, month;


--------------------------
month | year | expense | value
--------------------------
01 | 2024 | Food | 30.98
01 | 2024 | Apple | 9.99
01 | 2024 | Phone | 15.99
03 | 2024 | Food | 20.00
...

截至今天,这对于我的小应用程序来说已经足够了。现在我想增强应用程序并使用chart.js绘制图表,但不幸的是由于缺少数据,图表绘制错误。当特定月份(例如,特定月份)没有特定费用的行时,就会发生这种情况。 G。 2024 年 2 月没有食品费用,但 2024 年 3 月再次费用。

我的目标是再次查询表并修改查询语句以返回缺少费用类型和月份的行,然后返回 0 值。因此,对于上面的示例,由于缺少数据,缺少以下行:

--------------------------
month | year | expense | value
--------------------------
02 | 2024 | Food | 0
...

我用 google 搜索了一下,发现 CTE 可能是我问题的解决方案,但我在编写正确的 SQL 语句时仍然遇到问题。

sqlite
1个回答
0
投票

我们可以使用日历表方法。使用一个包含报告中显示的所有日期的表格,另一个包含所有费用的表格。

WITH dates AS (
    SELECT DISTINCT strftime("%m", VALUATIONDATE) AS month,
                    strftime("%Y", VALUATIONDATE) AS year
    FROM Transactions
),
expenses AS (
    SELECT DISTINCT expense
    FROM Transactions
)

SELECT 
    e.expense, 
    COALESCE(SUM(t.value), 0) AS balance,
    d.month,
    d.year
FROM dates d
CROSS JOIN expenses e
LEFT JOIN Transactions t
    ON d.month = strftime("%m", t.VALUATIONDATE) AND
       d.year = strftime("%Y", t.VALUATIONDATE) AND
       t.expense = e.expense
GROUP BY e.expense, d.month, d.year
ORDER BY e.expense, d.year, d.month;
© www.soinside.com 2019 - 2024. All rights reserved.