我有一个查询用于显示队列中的信息,部分信息显示属于父实体(更改)的子实体(包和实验室)的数量。然而,它们不是显示每种类型儿童的个人数量,而是相互相乘。
在下面的例子中,应该有3个实验室和18个包,但是它们相互相乘,每个输出为54个。
以下是查询的违规部分。
SELECT cef.ChangeId, COUNT(pac.PackageId) AS 'Packages', COUNT(lab.LabRequestId) AS 'Labs'
FROM dbo.ChangeEvaluationForm cef
LEFT JOIN dbo.Lab
ON cef.ChangeId = Lab.ChangeId
LEFT JOIN dbo.Package pac
ON (cef.ChangeId = pac.ChangeId AND pac.PackageStatus != 6 AND pac.PackageStatus !=7)
WHERE cef.ChangeId = 255
GROUP BY cef.ChangeId
我觉得这很明显,但我没有想到如何修复它,所以两个计数彼此独立,就像我应该这样。在我的任何研究中似乎都没有这样的场景。任何人都可以指导我朝正确的方向发展吗?
答案 0 :(得分:2)
因为您通过每个左连接将源行相乘。所以有时候你更有可能cross join
。
SELECT cef.ChangeId, p.Packages, l.Labs
FROM dbo.ChangeEvaluationForm cef
OUTER APPLY(
SELECT COUNT(*) as Labs
FROM dbo.Lab
WHERE cef.ChangeId = Lab.ChangeId
) l
OUTER APPLY(
SELECT COUNT(*) AS Packages
FROM dbo.Package pac
WHERE (cef.ChangeId = pac.ChangeId AND pac.PackageStatus != 6 AND pac.PackageStatus !=7)
) p
WHERE cef.ChangeId = 255
GROUP BY cef.ChangeId
现在可能不需要GROUP BY
。
答案 1 :(得分:1)
从您的问题来看,很难得出您对查询的期望结果。所以我认为你想要以下结果:
+----------+----------+------+
| ChangeId | Packages | Labs |
+----------+----------+------+
| 255 | 18 | 3 |
+----------+----------+------+
如果您正在寻找上述结果,请尝试以下查询。
SELECT cef.ChangeId, ISNULL(pac.PacCount, 0) AS 'Packages', ISNULL(Lab.LabCount, 0) AS 'Labs'
FROM dbo.ChangeEvaluationForm cef
LEFT JOIN (SELECT Lab.ChangeId, COUNT(*) LabCount FROM dbo.Lab GROUP BY) Lab
ON cef.ChangeId = Lab.ChangeId
LEFT JOIN (SELECT pac.ChangeId, COUNT(*) PacCount FROM dbo.Package pac WHERE pac.PackageStatus != 6 AND pac.PackageStatus !=7 GROUP BY pac.ChangeId) pac
ON cef.ChangeId = pac.ChangeId
WHERE cef.ChangeId = 255
查询说明:
PackageStatus
表格中移动了pac
过滤器。因此,不受欢迎的记录不会让我们的计数变得混乱。 答案 2 :(得分:0)
您从dbo.ChangeEvaluationForm表(您的示例中的ChangeId = 255)开始使用特定的ChangeId,然后加入dbo.Lab表。这个连接使得你的结果从1行变为3,考虑到有3个Labs,其中ChangeId = 255.你的问题是在下一个连接中,你将使用dbo.Package表加入前一个连接的所有3个结果行, ChangeId = 255的18行。对于pac.PackageId和lab.LabRequestId列的结果计数将是3 x 18 = 54。
为了得到你想要的东西,有两个简单的解决方案: