如何在第三个查询中包含来自其他两个表的过滤行数?
Posted
技术标签:
【中文标题】如何在第三个查询中包含来自其他两个表的过滤行数?【英文标题】:How do I include filtered rowcounts from two other tables in a query of a third? 【发布时间】:2009-01-22 02:55:01 【问题描述】:我有一个 mysql 数据库,其中包含三个需要在查询中组合的表:计划、注册和候补名单。他们正在实施一个基本的班级注册系统。
Schedule 包含已安排的课程。当用户注册课程时,他们的用户帐户 id 和预定课程的 id 存储在注册中。如果某个班级已满员,则将它们存储在候补名单中。这三个表共享一个 scheduleId 列,用于标识每个类。
当我查询日程表时,我还需要返回已注册和等待列表列,这些列表示已注册并等待特定 scheduleId 的用户数。
我想出的一个初步查询是:
select s.id, s.classDate, s.instructor, COUNT(e.id) as enrolled
from schedule as s
left outer join enrolled as e
on s.id = e.scheduleId
group by s.id
其中一个都可以,但显然我无法以这种方式获取已注册和候补表的值。 任何人都可以提出一个好的方法吗?
【问题讨论】:
【参考方案1】:使用嵌套的 SELECT 查询。假设您的架构有一点点,像这样的东西怎么样(可能不适用于某些 SQL 风格):
select s.id, s.classDate, s.instructor,
(select COUNT(e.id) from enrolled e where e.scheduleId = s.id) as enrolled,
(select COUNT(w.id) from waitlist w where w.scheduleId = s.id) as waiting
from schedule as s
group by s.id
【讨论】:
【参考方案2】:我会用另一个左连接和两个内联计数(不同)
select s.id, s.classDate, s.instructor ,
count(distinct e.id) as enrolled,
count(distinct w.id) as waiting
from schedule as s
left outer join enrolled as e
on s.id = e.scheduleID
left outer join waitlist as w
on s.id = w.scheduleID
group by s.id
当我运行这种方法与子查询相比时,它的执行速度大约是它的两倍,但我正在查看一个非常小的结果集。
【讨论】:
【参考方案3】:两种快捷方式:
1- 使用COUNT(DISTINCT e.id), COUNT(DISTINCT w.id)
获取每个表中唯一实例的数量,然后加入两者。这可能是非常低效的。
2- 在FROM
子句中使用子查询(仅适用于 MySQL 5.0 及更高版本):
SELECT s.id, s.classDate, s.instructor, tmpE.c AS enrolled, tmpW.c AS waiting
FROM
schedule AS s,
( SELECT scheduleID, COUNT(*) AS c FROM enrolled GROUP BY scheduleID ) AS tmpE,
( SELECT scheduleID, COUNT(*) AS c FROM waiting GROUP BY scheduleID ) AS tmpW
WHERE
s.id = e.scheduleID
AND s.id = w.scheduleID
GROUP BY s.id
不过,我可能错过了那里的左连接。
【讨论】:
以上是关于如何在第三个查询中包含来自其他两个表的过滤行数?的主要内容,如果未能解决你的问题,请参考以下文章