妥妥的'Joining'两个交叉应用
Properly 'Joining' two Cross Applies
我有一个包含三个交叉应用的查询,这些应用从三个不同的 table 收集数据。第一个 Cr-Ap 辅助第二和第三个 Cr-Ap。它为'cartridge'找到某个笔芯的最新ID,ID越高笔芯越新。
第二个和第三个 Cr-Ap 收集已重新填充的物品和在最近一次重新填充下已分发的物品的总和。
如果我 运行 分别查询 Cr-Ap 2 或 3,输出将类似于:
ID Amount
1 100
2 1000
3 100
4 0
5 0
etc
Amount 可以是分配的或重新填充的物品的数量。
只是我不想 运行 这些查询分开,我希望它们彼此相邻。
所以我想要的是 table 看起来像这样:
ID Refill Dispense
1 100 1
2 1000 5
3 100 7
4 0 99
5 0 3
etc
我的直觉告诉我要做
INNER JOIN crossaply2 ON crossapply3.ID = crossapply2.ID
但这行不通。我对 SQL 还是个新手,所以我不太清楚我可以加入什么不能加入,我所知道的是您可以使用交叉应用作为加入(有点?)。我想这可能是我需要做的,我只是不知道怎么做。
但事实并非如此,还有另一种复杂情况,有些笔芯没有分配任何东西。在这些情况下,我为 dispenses 编写的 crossapply 不会 return 为那个 refillID 做任何事情。什么都没有,我不是说 NULL,我的意思是它只是跳过了 refillID。但我希望在这些情况下看到 0。因为它只是跳过那些我无法让 COALESCE 或 ISNULL 工作的 ID,所以这也可能会使这两个应用程序的连接复杂化。因为 INNER JOIN 会跳过没有分配量的任何行,即使有我希望看到的重新填充量。
这是我的代码:
-- Dispensed SUM and Refilled SUM combined
SELECT [CartridgeRefill].[FK_CartridgeRegistration_Id]
,Refills.Refilled
,Dispenses.Dispensed
FROM [CartridgeRefill]
CROSS APPLY(
SELECT MAX([CartridgeRefill].[Id]) AS RecentRefillID
FROM [CartridgeRefill]
GROUP BY [CartridgeRefill].[FK_CartridgeRegistration_Id]
) AS RecentRefill
CROSS APPLY(
SELECT [CartridgeRefill].[FK_CartridgeRegistration_Id] AS RefilledID
,SUM([CartridgeRefillMedication].[Amount]) AS Refilled
FROM [CartridgeRefillMedication]
INNER JOIN [CartridgeRefill] ON [CartridgeRefillMedication].[FK_CartridgeRefill_Id] = [CartridgeRefill].[Id]
WHERE [CartridgeRefillMedication].[FK_CartridgeRefill_Id] = RecentRefill.RecentRefillID
GROUP BY [CartridgeRefill].[FK_CartridgeRegistration_Id]
) AS Refills
CROSS APPLY(
SELECT [CartridgeRefill].[FK_CartridgeRegistration_Id] AS DispensedID
,SUM([CartridgeDispenseAttempt].[Amount]) AS Dispensed
FROM [CartridgeDispenseAttempt]
INNER JOIN [CartridgeRefill] ON [CartridgeDispenseAttempt].[FK_CartridgeRefill_Id] = [CartridgeRefill].[Id]
WHERE [CartridgeDispenseAttempt].[FK_CartridgeRefill_Id] = RecentRefill.RecentRefillID
GROUP BY [CartridgeRefill].[FK_CartridgeRegistration_Id]
) AS Dispenses
GO
这段代码的输出结果如下:
1 300 1
1 300 1
1 200 194
1 200 194
1 200 8
1 200 8
1 0 39
1 0 39
1 100 14
1 100 14
1 200 1
1 200 1
1 0 28
1 0 28
1 1000 102
1 1000 102
1 1000 557
1 1000 557
1 2000 92
1 2000 92
1 100 75
1 100 75
1 100 100
1 100 100
1 100 51
1 100 51
1 600 28
1 600 28
1 200 47
1 200 47
1 200 152
1 200 152
1 234 26
1 234 26
1 0 227
1 0 227
1 10 6
1 10 6
1 300 86
1 300 86
1 0 194
1 0 194
1 500 18
1 500 18
1 1000 51
1 1000 51
1 1000 56
1 1000 56
1 500 48
1 500 48
1 0 10
1 0 10
1 1500 111
1 1500 111
1 56 79
1 56 79
1 100 6
1 100 6
1 44 134
1 44 134
1 1000 488
1 1000 488
1 100 32
1 100 32
1 100 178
1 100 178
1 500 672
1 500 672
1 200 26
1 200 26
1 500 373
1 500 373
1 100 10
1 100 10
1 900 28
1 900 28
2 900 28
2 900 28
2 900 28
etc
这完全是胡说八道,我无能为力,它持续了大约 20k 行并最终遍历了所有 ID。
非常感谢任何帮助:)
看起来有点过于复杂了。
尝试
WITH cr AS (
SELECT [FK_CartridgeRegistration_Id]
,MAX([CartridgeRefill].[Id]) RecentRefillID
FROM [CartridgeRefill]
GROUP BY [FK_CartridgeRegistration_Id]
)
SELECT cr.[FK_CartridgeRegistration_Id], Refills.Refilled, Dispenses.Dispensed
FROM cr
CROSS APPLY(
SELECT SUM(crm.[Amount]) AS Refilled
FROM [CartridgeRefillMedication] crm
WHERE crm.[FK_CartridgeRefill_Id] = cr.RecentRefillID
) AS Refills
CROSS APPLY(
SELECT SUM(cda.[Amount]) AS Dispensed
FROM [CartridgeDispenseAttempt] cda
WHERE cda.[FK_CartridgeRefill_Id] = cr.RecentRefillID
) AS Dispenses;
我有一个包含三个交叉应用的查询,这些应用从三个不同的 table 收集数据。第一个 Cr-Ap 辅助第二和第三个 Cr-Ap。它为'cartridge'找到某个笔芯的最新ID,ID越高笔芯越新。
第二个和第三个 Cr-Ap 收集已重新填充的物品和在最近一次重新填充下已分发的物品的总和。
如果我 运行 分别查询 Cr-Ap 2 或 3,输出将类似于:
ID Amount
1 100
2 1000
3 100
4 0
5 0
etc
Amount 可以是分配的或重新填充的物品的数量。
只是我不想 运行 这些查询分开,我希望它们彼此相邻。 所以我想要的是 table 看起来像这样:
ID Refill Dispense
1 100 1
2 1000 5
3 100 7
4 0 99
5 0 3
etc
我的直觉告诉我要做
INNER JOIN crossaply2 ON crossapply3.ID = crossapply2.ID
但这行不通。我对 SQL 还是个新手,所以我不太清楚我可以加入什么不能加入,我所知道的是您可以使用交叉应用作为加入(有点?)。我想这可能是我需要做的,我只是不知道怎么做。
但事实并非如此,还有另一种复杂情况,有些笔芯没有分配任何东西。在这些情况下,我为 dispenses 编写的 crossapply 不会 return 为那个 refillID 做任何事情。什么都没有,我不是说 NULL,我的意思是它只是跳过了 refillID。但我希望在这些情况下看到 0。因为它只是跳过那些我无法让 COALESCE 或 ISNULL 工作的 ID,所以这也可能会使这两个应用程序的连接复杂化。因为 INNER JOIN 会跳过没有分配量的任何行,即使有我希望看到的重新填充量。 这是我的代码:
-- Dispensed SUM and Refilled SUM combined
SELECT [CartridgeRefill].[FK_CartridgeRegistration_Id]
,Refills.Refilled
,Dispenses.Dispensed
FROM [CartridgeRefill]
CROSS APPLY(
SELECT MAX([CartridgeRefill].[Id]) AS RecentRefillID
FROM [CartridgeRefill]
GROUP BY [CartridgeRefill].[FK_CartridgeRegistration_Id]
) AS RecentRefill
CROSS APPLY(
SELECT [CartridgeRefill].[FK_CartridgeRegistration_Id] AS RefilledID
,SUM([CartridgeRefillMedication].[Amount]) AS Refilled
FROM [CartridgeRefillMedication]
INNER JOIN [CartridgeRefill] ON [CartridgeRefillMedication].[FK_CartridgeRefill_Id] = [CartridgeRefill].[Id]
WHERE [CartridgeRefillMedication].[FK_CartridgeRefill_Id] = RecentRefill.RecentRefillID
GROUP BY [CartridgeRefill].[FK_CartridgeRegistration_Id]
) AS Refills
CROSS APPLY(
SELECT [CartridgeRefill].[FK_CartridgeRegistration_Id] AS DispensedID
,SUM([CartridgeDispenseAttempt].[Amount]) AS Dispensed
FROM [CartridgeDispenseAttempt]
INNER JOIN [CartridgeRefill] ON [CartridgeDispenseAttempt].[FK_CartridgeRefill_Id] = [CartridgeRefill].[Id]
WHERE [CartridgeDispenseAttempt].[FK_CartridgeRefill_Id] = RecentRefill.RecentRefillID
GROUP BY [CartridgeRefill].[FK_CartridgeRegistration_Id]
) AS Dispenses
GO
这段代码的输出结果如下:
1 300 1
1 300 1
1 200 194
1 200 194
1 200 8
1 200 8
1 0 39
1 0 39
1 100 14
1 100 14
1 200 1
1 200 1
1 0 28
1 0 28
1 1000 102
1 1000 102
1 1000 557
1 1000 557
1 2000 92
1 2000 92
1 100 75
1 100 75
1 100 100
1 100 100
1 100 51
1 100 51
1 600 28
1 600 28
1 200 47
1 200 47
1 200 152
1 200 152
1 234 26
1 234 26
1 0 227
1 0 227
1 10 6
1 10 6
1 300 86
1 300 86
1 0 194
1 0 194
1 500 18
1 500 18
1 1000 51
1 1000 51
1 1000 56
1 1000 56
1 500 48
1 500 48
1 0 10
1 0 10
1 1500 111
1 1500 111
1 56 79
1 56 79
1 100 6
1 100 6
1 44 134
1 44 134
1 1000 488
1 1000 488
1 100 32
1 100 32
1 100 178
1 100 178
1 500 672
1 500 672
1 200 26
1 200 26
1 500 373
1 500 373
1 100 10
1 100 10
1 900 28
1 900 28
2 900 28
2 900 28
2 900 28
etc
这完全是胡说八道,我无能为力,它持续了大约 20k 行并最终遍历了所有 ID。 非常感谢任何帮助:)
看起来有点过于复杂了。 尝试
WITH cr AS (
SELECT [FK_CartridgeRegistration_Id]
,MAX([CartridgeRefill].[Id]) RecentRefillID
FROM [CartridgeRefill]
GROUP BY [FK_CartridgeRegistration_Id]
)
SELECT cr.[FK_CartridgeRegistration_Id], Refills.Refilled, Dispenses.Dispensed
FROM cr
CROSS APPLY(
SELECT SUM(crm.[Amount]) AS Refilled
FROM [CartridgeRefillMedication] crm
WHERE crm.[FK_CartridgeRefill_Id] = cr.RecentRefillID
) AS Refills
CROSS APPLY(
SELECT SUM(cda.[Amount]) AS Dispensed
FROM [CartridgeDispenseAttempt] cda
WHERE cda.[FK_CartridgeRefill_Id] = cr.RecentRefillID
) AS Dispenses;