Sql 计算多个不同的一对多关系
我有以下SQL:Sql 计算多个不同的一对多关系,sql,sql-server,Sql,Sql Server,我有以下SQL: SELECT j.AssocJobKey , COUNT(DISTINCT o.ID) AS SubjectsOrdered , COUNT(DISTINCT s.ID) AS SubjectsShot FROM Jobs j LEFT JOIN Orders o ON o.AssocJobKey = j.AssocJobKey LEFT JOIN Subjects s ON j.AssocJobKey = s.AssocJobKey GROUP BY j.AssocJobK
SELECT j.AssocJobKey
, COUNT(DISTINCT o.ID) AS SubjectsOrdered
, COUNT(DISTINCT s.ID) AS SubjectsShot
FROM Jobs j
LEFT JOIN Orders o ON o.AssocJobKey = j.AssocJobKey
LEFT JOIN Subjects s ON j.AssocJobKey = s.AssocJobKey
GROUP BY
j.AssocJobKey
,j.JobYear
基本结构是作业是父项,该父项由AssocJobKey唯一,并且与主题和订单具有一对多关系。
查询给出了我想要的,输出如下所示:
| AssocJobKey | SubjectsOrdered | SubjectsShot |
|-----------------------|------------------------|---------------------|
| BAT-H181 | 107 | 830 |
|--------------------- |------------------------|---------------------|
| BAT-H131 | 226 | 1287 |
问题是查询太重了,而且我的内存正在急剧增加,我不可能在一个大数据集上运行它。如果我删除了相应计数上的一个左连接,查询将立即执行,没有问题。所以,不知何故,事情在两个左连接之间的反弹比它们应该的要多,但我不明白它们为什么会这样
真的希望尽可能避免加入子选择。您的查询为每个作业生成笛卡尔积。这是一个很大的问题——您的第二行生成了大约500k行
COUNT(DISTINCT)
然后必须计算出这个笛卡尔乘积中的唯一ID
解决方案很简单:预聚合:
SELECT j.AssocJobKey, o.SubjectsOrdered, s.SubjectsShot
FROM Jobs j LEFT JOIN
(SELECT o.AssocJobKey, COUNT(*) as SubjectsOrdered
FROM Orders o
GROUP BY o.AssocJobKey
) o
ON o.AssocJobKey = j.AssocJobKey LEFT JOIN
(SELECT j.AssocJobKey, COUNT(s.ID) AS SubjectsShot
FROM Subjects s
GROUP BY j.AssocJobKey
) s
ON j.AssocJobKey = s.AssocJobKey;
这使得我认为某些假设是合理的:
- 订单和主题表中的
s是唯一的且非空id
是唯一的作业。AssocJobKey
通常,对于不同维度上的这些类型的联接,
COUNT(DISTINCT)
是一个合理的解决方案(查询当然更简单)。当最多有几个值时,这是正确的。感谢您提供有关笛卡尔积的信息,我从来不知道这个问题被称为什么。我希望在我的选择中避免选择,我认为它们看起来很糟糕,我总是寻找一个可以避免它们的解决方案。我想这是没办法的。谢谢