Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 计算多个不同的一对多关系_Sql_Sql Server - Fatal编程技术网

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

我有以下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.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;
这使得我认为某些假设是合理的:

  • 订单和主题表中的
    id
    s是唯一的且非空
  • 作业。AssocJobKey
    是唯一的
如果其中任何一个都不是真的,那么可以很容易地调整查询,但它们看起来像是合理的假设


通常,对于不同维度上的这些类型的联接,
COUNT(DISTINCT)
是一个合理的解决方案(查询当然更简单)。当最多有几个值时,这是正确的。

感谢您提供有关笛卡尔积的信息,我从来不知道这个问题被称为什么。我希望在我的选择中避免选择,我认为它们看起来很糟糕,我总是寻找一个可以避免它们的解决方案。我想这是没办法的。谢谢