不同桌子上的多个计数 - 帮助我更精通

时间:2013-10-19 12:30:28

标签: mysql sql

我想成为一名更好的查询作家。我有一个查询,它使用一些子选项来获取我的数据库上不同表的计数。我不确定它是最有效的方法。我尝试使用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.)完成第一个查询结果的最有效方法是什么?谢谢!

2 个答案:

答案 0 :(得分:1)

  

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

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

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

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

  

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

您的原始查询没有任何问题,除了您可以删除外部A的{​​{1}}子句,如下所示:

SELECT

答案 1 :(得分: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

我希望这会对你有所帮助。