1

我正在努力成为一个更好的查询作者。我有一个查询,它使用一些子选择来获取数据库中不同表的计数。我不确定它是最有效的方法。我尝试使用 LEFT JOIN 让它更好地工作,但它没有得出正确的结果。

这是“工作”查询:

Select orgID,
(SELECT COUNT(recordID) FROM adoption WHERE orgID = 10031 
AND adoptDate BETWEEN '2013-01-01' AND '2013-10-19') as adoptTotal,
(SELECT COUNT(petID) FROM pets WHERE orgID = 10031
AND intakeDate BETWEEN '2013-01-01' AND '2013-10-19') as intakeTotal,
(SELECT COUNT(appID) FROM applications WHERE orgID = 10031 
AND applyDate BETWEEN '2013-01-01' AND '2013-10-19') as appTotal,
(SELECT COUNT(appID) FROM `ifosterpets`.`apps`WHERE orgID = 10031 
AND dateAdded BETWEEN '2013-01-01' AND '2013-10-19' and isactive = 1) as fosterApps,
(SELECT COUNT(matchID) FROM petmatches WHERE orgID = 10031
AND dateAdded BETWEEN '2013-01-01' AND '2013-10-19' AND isActive = 1) as matchTotals
FROM `memberships`.`orgs`
WHERE orgID = 10031 

这是我尝试得到错误结果的方法:

SELECT COUNT(ad.recordID) as adoptTotal, COUNT(p.petID) as intakeTotal, COUNT(a.appID) as appTotal, COUNT(f.appID) as fosterApps, COUNT(m.matchID) as matchTotals
FROM `memberships`.`orgs` o LEFT JOIN adoption ad ON ad.orgID = o.orgID
LEFT JOIN pets p ON p.orgID = o.orgID
LEFT JOIN applications a ON a.orgID = o.orgID
LEFT JOIN `ifosterpets`.`apps` f ON f.orgID = o.orgID
LEFT JOIN petmatches m ON m.orgID = o.orgID
WHERE ad.adoptDate BETWEEN '2013-01-01' AND '2013-10-19'
AND p.intakeDate BETWEEN '2013-01-01' AND '2013-10-19'
AND a.applyDate BETWEEN '2013-01-01' AND '2013-10-19'
AND f.dateAdded BETWEEN '2013-01-01' AND '2013-10-19'
and f.isactive = 1
AND m.dateAdded BETWEEN '2013-01-01' AND '2013-10-19' 
AND m.isActive = 1
AND o.orgID = 10031

这是一个两部分的问题:1)我在 LEFT JOIN 查询上做错了什么?2.) 完成第一个查询结果的最有效方法是什么?谢谢!

4

2 回答 2

1

我在LEFT JOIN查询中做错了什么?

回想一下,连接产生记录的笛卡尔积,或者简单地说,结果行包含通过连接连接的表中的数据组合。当连接中的两个表相关时,此类组合的数量等于与连接条件匹配的行数。这就是“事件的正常过程”。

但是,当表不相关时,SQL 会生成它们行的所有可能组合。这种组合的数量随着单个表的行数的乘积而增长。

考虑一个示例,您将表连接A到表BC,其中ABA相关C,但BC不相关。如果A' 连接B产生 10 条记录,而A' 连接C产生 5 条记录,A' 连接BC一起产生 50 条记录。如果您D在连接中添加 6 行的A表,则四表连接将产生 300 条记录。我希望您看到图片:当您不应该将彼此不相关的表添加到连接时,结果的数量会增长得非常快。

完成第一个查询结果的最有效方法是什么?

您的原始查询没有任何问题,只是您可以删除外部SELECT'FROM子句,如下所示:

Select
    10031 as orgID
,   (SELECT COUNT(recordID) FROM adoption WHERE orgID = 10031 AND adoptDate BETWEEN '2013-01-01' AND '2013-10-19') as adoptTotal
,   (SELECT COUNT(petID) FROM pets WHERE orgID = 10031 AND intakeDate BETWEEN '2013-01-01' AND '2013-10-19') as intakeTotal
,   (SELECT COUNT(appID) FROM applications WHERE orgID = 10031 AND applyDate BETWEEN '2013-01-01' AND '2013-10-19') as appTotal
,   (SELECT COUNT(appID) FROM `ifosterpets`.`apps`WHERE orgID = 10031 AND dateAdded BETWEEN '2013-01-01' AND '2013-10-19' and isactive = 1) as fosterApps
,   (SELECT COUNT(matchID) FROM petmatches WHERE orgID = 10031 AND dateAdded BETWEEN '2013-01-01' AND '2013-10-19' AND isActive = 1) as matchTotals
于 2013-10-19T12:48:40.880 回答
0

由于您使用左连接,您将获得重复的ID。所以在查询中使用distinct

例如如下:

select  COUNT(distinct t1.id),
        COUNT(distinct t2.tbl2id),
        COUNT( distinct t3.tbl3id) 
from table1 t1 
left join table2 t2 on t1.orgid = t2.orgid 
left join table3 t3 on t1.orgid = t3.orgid 
where t1.orgid = 1

我希望这能帮到您。

于 2013-10-19T13:01:19.940 回答