一个交叉中的两个聚合可能吗?

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 都有单独的总计。如果是这样,那么你的样本结果是不合理的,因为 ids 是重复的。但这似乎可以做一些有用的事情:

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