一个交叉中的两个聚合可能吗?
Two aggregates in one cross apply possible?
我是 SQL 的新手,我正在尝试使用 CROSS APPLY,对此我知之甚少。
我正在尝试从两个不同的表中提取按 ID 排序的项目的两个 SUM。墨盒分配的所有物品的一个 SUM,重新填充到墨盒中的所有物品的一个 SUM。配药和补充装在不同的桌子上。在示例 1 中,您可以看到一段适用于这两个 SUM 之一的代码,目前它适用于分配的 SUM,但如果我为重新填充的 SUM 更改所有内容,它也可以工作。重点是我只能在这个 CROSS APPLY 中做一个 SUM,不管两者中的哪一个。
所以当我尝试在这个 CROSS APPLY 中提取两个 SUM 时出错,可能是因为我真的不知道我在做什么。我尝试使用示例 2 中的代码(几乎是相同的代码)来执行此操作。
一些额外的上下文:
这里有两个ID很重要:
CartridgeRefill.FK_CartridgeRegistration_Id
(或 ID)是墨盒本身的 ID。 FK_CartridgeRefill_Id
是笔芯的 ID,一个墨盒可以经过多次笔芯,并且分配是根据从中分配的笔芯进行注册的。这就是为什么您可以在输出中多次看到相同的 ID。
示例 1:
SELECT CartridgeRefill.FK_CartridgeRegistration_Id AS ID, Sums.Dispensed
FROM CartridgeRefillItem
CROSS APPLY (
SELECT SUM(CartridgeDispenseAttempt.Amount) AS Dispensed
FROM CartridgeDispenseAttempt
WHERE CartridgeRefillItem.FK_CartridgeRefill_Id = CartridgeDispenseAttempt.FK_CartridgeRefill_Id
) AS Sums
JOIN CartridgeRefill ON CartridgeRefillItem.FK_CartridgeRefill_Id = CartridgeRefill.FK_CartridgeRefill_Id
示例 2:
SELECT CartridgeRefill.FK_CartridgeRegistration_Id AS ID, Sums.Dispensed, Sums.Refilled
FROM CartridgeRefillItem
CROSS APPLY (
SELECT SUM(CartridgeDispenseAttempt.Amount) AS Dispensed
,SUM(CartridgeRefillItem.Amount) AS Refilled
FROM CartridgeDispenseAttempt
WHERE CartridgeRefillItem.FK_CartridgeRefill_Id = CartridgeDispenseAttempt.FK_CartridgeRefill_Id
) AS Sums
JOIN CartridgeRefill ON CartridgeRefillItem.FK_CartridgeRefill_Id = CartridgeRefill.FK_CartridgeRefill_Id
当我 运行 样本 1 我得到这个输出:
ID Dispensed
10 95
8 143
6 143
11 70
11 312
11 354
8 19
8 24
8 3
8 33
这个输出是正确的,它在它所属的 ID 旁边显示了分配的物品数量。
这是我在 运行 样本 2:
时得到的错误
Msg 4101, Level 15, State 1, Line 15
Aggregates on the right side of an APPLY cannot reference columns from the left side.
但我想看到的是:
ID Dispensed Refilled (example)
10 95 143
8 143 12
6 143 etc...
11 70
11 312
11 354
8 19
8 24
8 3
8 33
我觉得跟CROSS APPLY 运行逐行有关系?但同样,我仍然不完全知道我在做什么。任何帮助将不胜感激,请询问您需要知道的任何信息:)
错误不言自明,您不能 运行 使用 CROSS APPLY
之外的引用进行聚合。您需要通过添加额外的子查询来重写查询来计算 SUM
或使用 GROUP BY
子句。我很快就抓取了这个:
SELECT CartridgeRefill.FK_CartridgeRegistration_Id AS ID, Sums.Dispensed, SUM(CartridgeRefillMedication.Amount) AS Refilled
FROM CartridgeRefillItem
CROSS APPLY (
SELECT SUM(CartridgeDispenseAttempt.Amount) AS Dispensed
FROM CartridgeDispenseAttempt
WHERE CartridgeRefillItem.FK_CartridgeRefill_Id = CartridgeDispenseAttempt.FK_CartridgeRefill_Id
) AS Sums
JOIN CartridgeRefill ON CartridgeRefillMedication.FK_CartridgeRefill_Id = CartridgeRefill.FK_CartridgeRefill_Id
GROUP BY CartridgeRefill.FK_CartridgeRegistration_Id;
希望这能奏效。
您可能根本不需要聚合。行数没有减少,所以这可能是你想要的:
SELECT cr.FK_CartridgeRegistration_Id AS ID,
d.Dispensed, cr.Amount AS Refilled
FROM CartridgeRefillItem cr CROSS APPLY
(SELECT SUM(cd.Amount) AS Dispensed
FROM CartridgeDispenseAttempt c
WHERE cr.FK_CartridgeRefill_Id = cd.FK_CartridgeRefill_Id
) d;
我希望您希望每个 ID 都有单独的总计。如果是这样,那么你的样本结果是不合理的,因为 id
s 是重复的。但这似乎可以做一些有用的事情:
select id, sum(refill_amount) as refill_amount,
sum(dispensed_amount) as dispensed_amount
from ((select cr.FK_CartridgeRegistration_Id as id,
cr.Amount as refill_amount,
0 as dispensed_amount
from CartridgeRefillItem cr
) union all
(select cd.FK_CartridgeRegistration_Id as id,
0, cd.Amount
from CartridgeDispenseAttempt cd
)
) c
group by id
我是 SQL 的新手,我正在尝试使用 CROSS APPLY,对此我知之甚少。
我正在尝试从两个不同的表中提取按 ID 排序的项目的两个 SUM。墨盒分配的所有物品的一个 SUM,重新填充到墨盒中的所有物品的一个 SUM。配药和补充装在不同的桌子上。在示例 1 中,您可以看到一段适用于这两个 SUM 之一的代码,目前它适用于分配的 SUM,但如果我为重新填充的 SUM 更改所有内容,它也可以工作。重点是我只能在这个 CROSS APPLY 中做一个 SUM,不管两者中的哪一个。
所以当我尝试在这个 CROSS APPLY 中提取两个 SUM 时出错,可能是因为我真的不知道我在做什么。我尝试使用示例 2 中的代码(几乎是相同的代码)来执行此操作。
一些额外的上下文:
这里有两个ID很重要:
CartridgeRefill.FK_CartridgeRegistration_Id
(或 ID)是墨盒本身的 ID。 FK_CartridgeRefill_Id
是笔芯的 ID,一个墨盒可以经过多次笔芯,并且分配是根据从中分配的笔芯进行注册的。这就是为什么您可以在输出中多次看到相同的 ID。
示例 1:
SELECT CartridgeRefill.FK_CartridgeRegistration_Id AS ID, Sums.Dispensed
FROM CartridgeRefillItem
CROSS APPLY (
SELECT SUM(CartridgeDispenseAttempt.Amount) AS Dispensed
FROM CartridgeDispenseAttempt
WHERE CartridgeRefillItem.FK_CartridgeRefill_Id = CartridgeDispenseAttempt.FK_CartridgeRefill_Id
) AS Sums
JOIN CartridgeRefill ON CartridgeRefillItem.FK_CartridgeRefill_Id = CartridgeRefill.FK_CartridgeRefill_Id
示例 2:
SELECT CartridgeRefill.FK_CartridgeRegistration_Id AS ID, Sums.Dispensed, Sums.Refilled
FROM CartridgeRefillItem
CROSS APPLY (
SELECT SUM(CartridgeDispenseAttempt.Amount) AS Dispensed
,SUM(CartridgeRefillItem.Amount) AS Refilled
FROM CartridgeDispenseAttempt
WHERE CartridgeRefillItem.FK_CartridgeRefill_Id = CartridgeDispenseAttempt.FK_CartridgeRefill_Id
) AS Sums
JOIN CartridgeRefill ON CartridgeRefillItem.FK_CartridgeRefill_Id = CartridgeRefill.FK_CartridgeRefill_Id
当我 运行 样本 1 我得到这个输出:
ID Dispensed
10 95
8 143
6 143
11 70
11 312
11 354
8 19
8 24
8 3
8 33
这个输出是正确的,它在它所属的 ID 旁边显示了分配的物品数量。
这是我在 运行 样本 2:
时得到的错误Msg 4101, Level 15, State 1, Line 15
Aggregates on the right side of an APPLY cannot reference columns from the left side.
但我想看到的是:
ID Dispensed Refilled (example)
10 95 143
8 143 12
6 143 etc...
11 70
11 312
11 354
8 19
8 24
8 3
8 33
我觉得跟CROSS APPLY 运行逐行有关系?但同样,我仍然不完全知道我在做什么。任何帮助将不胜感激,请询问您需要知道的任何信息:)
错误不言自明,您不能 运行 使用 CROSS APPLY
之外的引用进行聚合。您需要通过添加额外的子查询来重写查询来计算 SUM
或使用 GROUP BY
子句。我很快就抓取了这个:
SELECT CartridgeRefill.FK_CartridgeRegistration_Id AS ID, Sums.Dispensed, SUM(CartridgeRefillMedication.Amount) AS Refilled
FROM CartridgeRefillItem
CROSS APPLY (
SELECT SUM(CartridgeDispenseAttempt.Amount) AS Dispensed
FROM CartridgeDispenseAttempt
WHERE CartridgeRefillItem.FK_CartridgeRefill_Id = CartridgeDispenseAttempt.FK_CartridgeRefill_Id
) AS Sums
JOIN CartridgeRefill ON CartridgeRefillMedication.FK_CartridgeRefill_Id = CartridgeRefill.FK_CartridgeRefill_Id
GROUP BY CartridgeRefill.FK_CartridgeRegistration_Id;
希望这能奏效。
您可能根本不需要聚合。行数没有减少,所以这可能是你想要的:
SELECT cr.FK_CartridgeRegistration_Id AS ID,
d.Dispensed, cr.Amount AS Refilled
FROM CartridgeRefillItem cr CROSS APPLY
(SELECT SUM(cd.Amount) AS Dispensed
FROM CartridgeDispenseAttempt c
WHERE cr.FK_CartridgeRefill_Id = cd.FK_CartridgeRefill_Id
) d;
我希望您希望每个 ID 都有单独的总计。如果是这样,那么你的样本结果是不合理的,因为 id
s 是重复的。但这似乎可以做一些有用的事情:
select id, sum(refill_amount) as refill_amount,
sum(dispensed_amount) as dispensed_amount
from ((select cr.FK_CartridgeRegistration_Id as id,
cr.Amount as refill_amount,
0 as dispensed_amount
from CartridgeRefillItem cr
) union all
(select cd.FK_CartridgeRegistration_Id as id,
0, cd.Amount
from CartridgeDispenseAttempt cd
)
) c
group by id