我想成为一名更好的查询作家。我有一个查询,它使用一些子选项来获取我的数据库上不同表的计数。我不确定它是最有效的方法。我尝试使用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.)完成第一个查询结果的最有效方法是什么?谢谢!
答案 0 :(得分:1)
我在
LEFT JOIN
查询时做错了什么?
回想一下,联接生成记录的笛卡儿产品,或者简单地说,结果行包含通过连接连接的表中的数据组合。当连接中的两个表相关时,此类组合的数量等于与连接条件匹配的行数。那是“正常的事件过程”。
但是,当表不相关时,SQL会生成所有可能的行组合。这些组合的数量随着各个表的行数的乘积而增长。
考虑一个示例,其中您将表A
加入表B
和C
,其中A
与B
和A
相关联与C
相关,但B
和C
无关。如果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
我希望这会对你有所帮助。