SQL 使用 UNION ALL 前一行结果的表达式
SQL Expressions using result of previous row of UNION ALL
我有这两个 tables:
Collect: Date, Rute, Value_Collected...
Records: Date, Rute, Value, Type...
其他列与本例无关。所以我有这个工作代码:
SELECT
Totals.Date AS [Date],
Sum(Totals.Collected) AS [Collect],
Sum(Totals.Injected) AS [Injections],
Sum(Totals.Spent) AS [Expenses],
([Collect] + [Injections]) - [Expenses] AS [Total Day]
FROM (
SELECT
Records.Date AS [Date],
0 AS [Collected],
Sum(IIF(Type = 3,Records.Value,0)) AS [Injected],
Sum(IIF(Type <> 3,Records.Value,0)) AS [Spent]
FROM Records GROUP BY Records.Date
UNION ALL
SELECT
Collect.Date AS [Date],
Sum(Collect.Value_Collected) AS [Collected],
0 AS [Injected],
0 AS [Spent]
FROM Collect GROUP BY Collect.Date
) AS Totals GROUP BY Totals.Date
这给了我这个结果:
|Date |Collect |Injections |Expenses |Total Day
-----------------------------------------------------------
|5/09/2016 |.000 |[=13=] |[=13=] |.000 |
|6/09/2016 |.000 |[=13=] |[=13=] |.000 |
|7/09/2016 |.000 |[=13=] |[=13=] |.000 |
|11/09/2016 |2.000 |[=13=] |[=13=] |2.000|
|14/09/2016 |.000 |[=13=] |[=13=] |.000 |
|16/09/2016 |0.000 |[=13=] |.000 |.000 |
|30/09/2016 |[=13=] |.000 |.000 |.000 |
-----------------------------------------------------------
现在没问题,但是 [Total Day]
列的公式必须像这样计算 ([Total Day Of Last Row] + [Collect] + [Injections]) - [Expenses]
而不是 ([Collect] + [Injections]) - [Expenses]
才能得到我想要的结果:
|Date |Collect |Injections |Expenses |Total Day
-------------------------------------------------------------
|5/09/2016 |.000 |[=14=] |[=14=] |.000 |
|6/09/2016 |.000 |[=14=] |[=14=] |.000 |
|7/09/2016 |.000 |[=14=] |[=14=] |.000 |
|11/09/2016 |2.000 |[=14=] |[=14=] |2.000|
|14/09/2016 |.000 |[=14=] |[=14=] |9.000|
|16/09/2016 |0.000 |[=14=] |.000 |2.000|
|30/09/2016 |[=14=] |.000 |.000 |7.000|
-------------------------------------------------------------
但是我不知道如何获取前一行的[Total Day]
来计算当前行的[Total Day]
。如果我尝试 运行 [Totals]
的子查询,它会给我一个错误,因为它找不到 table Totals
。我认为这是因为它不是 "real" table,但我真的不知道如何实现它。非常感谢任何帮助。
PS:列的名称和 tables 最初是西班牙语,但出于某种目的进行了翻译,以便您可以理解我需要完成的工作。
从本质上讲,您需要按渐进日期计算各个字段的累计总和,这可以通过相关总和聚合子查询来处理。唯一的挑战是 MS Access 没有像其他 SQL 方言那样的 window 函数来重用派生的 table 查询。所以你需要在子查询中重复 union derived table:
SELECT main.Date, main.Collected AS [Collect],
main.Injected As [Injections], main.Spent As [Expenses],
Ccur((SELECT Sum(sub.Collected) + Sum(sub.Injected) - Sum(sub.Spent)
FROM
(SELECT Records.Date AS [Date], 0 AS [Collected],
Sum(IIF(Type = 3,Records.Value,0)) AS [Injected],
Sum(IIF(Type <> 3,Records.Value,0)) AS [Spent]
FROM Records GROUP BY Records.Date
UNION ALL
SELECT Collect.Date AS [Date],
Sum(Collect.Value_Collected) AS [Collected],
0 AS [Injected],
0 AS [Spent]
FROM Collect GROUP BY Collect.Date
) As sub
WHERE sub.Date <= main.Date)) As [Total Day]
FROM
(SELECT Records.Date AS [Date], 0 AS [Collected],
Sum(IIF(Type = 3,Records.Value,0)) AS [Injected],
Sum(IIF(Type <> 3,Records.Value,0)) AS [Spent]
FROM Records GROUP BY Records.Date
UNION ALL
SELECT Collect.Date AS [Date],
Sum(Collect.Value_Collected) AS [Collected],
0 AS [Injected],
0 AS [Spent]
FROM Collect GROUP BY Collect.Date
) As main
幸运的是,MS Access 确实维护了存储的查询对象,您可以在其中将 UNION 查询保存为单独的查询,并在新查询中引用它以获得更短的脚本:
SELECT main.Date, main.Collected As [Collect],
main.Injected As Injections, main.Spent As Expenses,
Ccur((SELECT Sum(sub.Collected) + Sum(sub.Injected) - Sum(sub.Spent)
FROM RecordsUnionQ As sub
WHERE sub.Date <= main.Date)) As [Total Day]
FROM RecordsUnionQ As main
使用支持CTE的SQLite 3,可以使用WITH()
子句来保持联合查询,避免在子查询中重复。 CTE 仅在 SQL 语句期间充当临时视图。
WITH main AS
(SELECT Records.Date AS [Date], 0 AS [Collected],
Sum(IIF(Type = 3,Records.Value,0)) AS [Injected],
Sum(IIF(Type <> 3,Records.Value,0)) AS [Spent]
FROM Records GROUP BY Records.Date
UNION ALL
SELECT Collect.Date AS [Date],
Sum(Collect.Value_Collected) AS [Collected],
0 AS [Injected],
0 AS [Spent]
FROM Collect GROUP BY Collect.Date)
SELECT main.Date, main.Collected AS [Collect],
main.Injected As [Injections], main.Spent As [Expenses],
Ccur((SELECT Sum(sub.Collected) + Sum(sub.Injected) - Sum(sub.Spent)
FROM main As sub
WHERE sub.Date <= main.Date)) As [Total Day]
FROM main;
我有这两个 tables:
Collect: Date, Rute, Value_Collected...
Records: Date, Rute, Value, Type...
其他列与本例无关。所以我有这个工作代码:
SELECT
Totals.Date AS [Date],
Sum(Totals.Collected) AS [Collect],
Sum(Totals.Injected) AS [Injections],
Sum(Totals.Spent) AS [Expenses],
([Collect] + [Injections]) - [Expenses] AS [Total Day]
FROM (
SELECT
Records.Date AS [Date],
0 AS [Collected],
Sum(IIF(Type = 3,Records.Value,0)) AS [Injected],
Sum(IIF(Type <> 3,Records.Value,0)) AS [Spent]
FROM Records GROUP BY Records.Date
UNION ALL
SELECT
Collect.Date AS [Date],
Sum(Collect.Value_Collected) AS [Collected],
0 AS [Injected],
0 AS [Spent]
FROM Collect GROUP BY Collect.Date
) AS Totals GROUP BY Totals.Date
这给了我这个结果:
|Date |Collect |Injections |Expenses |Total Day
-----------------------------------------------------------
|5/09/2016 |.000 |[=13=] |[=13=] |.000 |
|6/09/2016 |.000 |[=13=] |[=13=] |.000 |
|7/09/2016 |.000 |[=13=] |[=13=] |.000 |
|11/09/2016 |2.000 |[=13=] |[=13=] |2.000|
|14/09/2016 |.000 |[=13=] |[=13=] |.000 |
|16/09/2016 |0.000 |[=13=] |.000 |.000 |
|30/09/2016 |[=13=] |.000 |.000 |.000 |
-----------------------------------------------------------
现在没问题,但是 [Total Day]
列的公式必须像这样计算 ([Total Day Of Last Row] + [Collect] + [Injections]) - [Expenses]
而不是 ([Collect] + [Injections]) - [Expenses]
才能得到我想要的结果:
|Date |Collect |Injections |Expenses |Total Day
-------------------------------------------------------------
|5/09/2016 |.000 |[=14=] |[=14=] |.000 |
|6/09/2016 |.000 |[=14=] |[=14=] |.000 |
|7/09/2016 |.000 |[=14=] |[=14=] |.000 |
|11/09/2016 |2.000 |[=14=] |[=14=] |2.000|
|14/09/2016 |.000 |[=14=] |[=14=] |9.000|
|16/09/2016 |0.000 |[=14=] |.000 |2.000|
|30/09/2016 |[=14=] |.000 |.000 |7.000|
-------------------------------------------------------------
但是我不知道如何获取前一行的[Total Day]
来计算当前行的[Total Day]
。如果我尝试 运行 [Totals]
的子查询,它会给我一个错误,因为它找不到 table Totals
。我认为这是因为它不是 "real" table,但我真的不知道如何实现它。非常感谢任何帮助。
PS:列的名称和 tables 最初是西班牙语,但出于某种目的进行了翻译,以便您可以理解我需要完成的工作。
从本质上讲,您需要按渐进日期计算各个字段的累计总和,这可以通过相关总和聚合子查询来处理。唯一的挑战是 MS Access 没有像其他 SQL 方言那样的 window 函数来重用派生的 table 查询。所以你需要在子查询中重复 union derived table:
SELECT main.Date, main.Collected AS [Collect],
main.Injected As [Injections], main.Spent As [Expenses],
Ccur((SELECT Sum(sub.Collected) + Sum(sub.Injected) - Sum(sub.Spent)
FROM
(SELECT Records.Date AS [Date], 0 AS [Collected],
Sum(IIF(Type = 3,Records.Value,0)) AS [Injected],
Sum(IIF(Type <> 3,Records.Value,0)) AS [Spent]
FROM Records GROUP BY Records.Date
UNION ALL
SELECT Collect.Date AS [Date],
Sum(Collect.Value_Collected) AS [Collected],
0 AS [Injected],
0 AS [Spent]
FROM Collect GROUP BY Collect.Date
) As sub
WHERE sub.Date <= main.Date)) As [Total Day]
FROM
(SELECT Records.Date AS [Date], 0 AS [Collected],
Sum(IIF(Type = 3,Records.Value,0)) AS [Injected],
Sum(IIF(Type <> 3,Records.Value,0)) AS [Spent]
FROM Records GROUP BY Records.Date
UNION ALL
SELECT Collect.Date AS [Date],
Sum(Collect.Value_Collected) AS [Collected],
0 AS [Injected],
0 AS [Spent]
FROM Collect GROUP BY Collect.Date
) As main
幸运的是,MS Access 确实维护了存储的查询对象,您可以在其中将 UNION 查询保存为单独的查询,并在新查询中引用它以获得更短的脚本:
SELECT main.Date, main.Collected As [Collect],
main.Injected As Injections, main.Spent As Expenses,
Ccur((SELECT Sum(sub.Collected) + Sum(sub.Injected) - Sum(sub.Spent)
FROM RecordsUnionQ As sub
WHERE sub.Date <= main.Date)) As [Total Day]
FROM RecordsUnionQ As main
使用支持CTE的SQLite 3,可以使用WITH()
子句来保持联合查询,避免在子查询中重复。 CTE 仅在 SQL 语句期间充当临时视图。
WITH main AS
(SELECT Records.Date AS [Date], 0 AS [Collected],
Sum(IIF(Type = 3,Records.Value,0)) AS [Injected],
Sum(IIF(Type <> 3,Records.Value,0)) AS [Spent]
FROM Records GROUP BY Records.Date
UNION ALL
SELECT Collect.Date AS [Date],
Sum(Collect.Value_Collected) AS [Collected],
0 AS [Injected],
0 AS [Spent]
FROM Collect GROUP BY Collect.Date)
SELECT main.Date, main.Collected AS [Collect],
main.Injected As [Injections], main.Spent As [Expenses],
Ccur((SELECT Sum(sub.Collected) + Sum(sub.Injected) - Sum(sub.Spent)
FROM main As sub
WHERE sub.Date <= main.Date)) As [Total Day]
FROM main;