以下是我所拥有的三个表,其中session.id = signup.session_id和session.loc_id = location.id。最大覆盖是因为名称建议覆盖该位置的默认最大容量,因此IFNULL(session.max_override, location.max_cap)
。
mysql> SELECT * FROM session;
+----+---------------------+---------------+--------+
| id | date_time | max_override | loc_id |
+----+---------------------+---------------+--------+
| 1 | 2014-02-04 10:30:00 | 35 | 2 |
| 2 | 2014-02-04 17:00:00 | | 2 |
| 3 | 2014-02-06 11:30:00 | 50 | 2 |
| 4 | 2014-02-09 13:30:00 | | 1 |
+----+---------------------+---------------+--------+
mysql> SELECT * FROM location;
+-----------------+---------+
| id | location | max_cap |
+-----------------+---------+
| 1 | up | 20 |
| 2 | down | 103 |
| 3 | right | 50 |
| 4 | left | 50 |
+-----------------+---------+
mysql> SELECT * FROM signups;
+-----------------+------------+
| id | name | session_id |
+-----------------+------------+
| 1 | test | 3 |
| 2 | admin | 1 |
| 3 | meme | 2 |
| 4 | anna | 4 |
+-----------------+------------+
我试图创建的报告看起来很简单,但我不确定如何解决问题。以下是我希望报告/输出看起来像..
mysql> query ouput;
+------------+----------+-----------+----------+----------+-----------+----------+
| date | am_time | am_ses_id | am_spots | pm_time | pm_ses_id | pm_spots |
+------------+----------+-----------+----------+----------+-----------+----------+
| 2014-02-04 | 10:30 AM | 1 | 34 | 05:00 PM | 2 | 102 |
| 2014-02-06 | 11:30 AM | 3 | 49 | | | |
| 2014-02-09 | | | | 01:30 PM | 4 | 49 |
+------------+----------+-----------+----------+----------+-----------+----------+
我可以正确地对日期和时间进行分组,并设法使session_id
匹配,因为它全部在一个表中但是要计算上午/下午点,这只是计算注册表中的记录特定会话并根据具体情况从max_cap
或max_override
中扣除该值。
这就是我试过的
使用以下查询
SELECT
DATE_FORMAT(a.date_time,'%m/%d/%Y') AS ses_date,
DATE_FORMAT(a.date_time,'%r') AS ses_time,
a.id,
COUNT(b.id) as signed_up,
IFNULL(a.max_override,c.max_cap) AS cap
FROM
test.session a
LEFT JOIN
test.signups b
ON (b.session_id = a.id)
LEFT JOIN
test.location c
ON (c.id = a.loc_id)
GROUP BY b.session_id
我得到以下输出
+------------+----------+--------+-----------+------+
| date | ses_time | ses_id | signed_up | cap |
+------------+----------+--------+-----------+------+
| 2014-02-04 | 10:30 AM | 1 | 1 | 35 |
| 2014-02-04 | 05:00 PM | 2 | 1 | 103 |
| 2014-02-06 | 10:30 AM | 3 | 1 | 50 |
| 2014-02-09 | 10:30 AM | 4 | 1 | 50 |
+------------+----------+--------+-----------+------+
但是我似乎无法找到一种方法只按日期对其进行分组,因此输出会显示为所需!我不知道我是否应该结合两个查询。
答案 0 :(得分:1)
这是一种非常复杂的做法......
sqlfiddle:http://sqlfiddle.com/#!2/d85ca/11
select c.ses_date `date`, a.ses_time am_time, a.id am_ses_id, a.cap-a.signed_up am_spots,
b.ses_time pm_time, b.id pm_ses_id, b.cap-b.signed_up pm_spots
from (
select distinct DATE_FORMAT(a.date_time,'%m/%d/%Y') ses_date
from session a) c
left join (
SELECT
DATE_FORMAT(a.date_time,'%m/%d/%Y') AS ses_date,
DATE_FORMAT(a.date_time,'%r') AS ses_time,
a.id,
COUNT(b.id) as signed_up,
IFNULL(a.max_override,c.max_cap) AS cap
FROM
session a
LEFT JOIN
signups b
ON (b.session_id = a.id)
LEFT JOIN
location c
ON (c.id = a.loc_id)
where date_format(a.date_time, '%p') = 'AM'
GROUP BY b.session_id) a on c.ses_date = a.ses_date
left join (
SELECT
DATE_FORMAT(a.date_time,'%m/%d/%Y') AS ses_date,
DATE_FORMAT(a.date_time,'%r') AS ses_time,
a.id,
COUNT(b.id) as signed_up,
IFNULL(a.max_override,c.max_cap) AS cap
FROM
session a
LEFT JOIN
signups b
ON (b.session_id = a.id)
LEFT JOIN
location c
ON (c.id = a.loc_id)
where date_format(a.date_time, '%p') = 'PM'
GROUP BY b.session_id) b on c.ses_date = b.ses_date;
答案 1 :(得分:0)
您需要使用JOIN运算符让SQL DB知道表之间的关系。
在这种情况下,也可以更容易地执行子查询来获取计数(以避免GROUP BY
)。我白天没有将AM和PM分开,但你可以这样做。
SELECT session.date_time,
IFNULL(session.max_override,location.max_cap)-(
SELECT COUNT(signups.id)
FROM signups
WHERE signups.session_id = session.id) as avail_spots
FROM session LEFT JOIN location ON session.loc_id = location.id;
请注意LEFT JOIN
将2014-02-04 17:00:00
包含NULL
avail_spots,因为max_override和max_cap都没有值,而INNER JOIN
根本不会报告该会话。
编辑:一旦您获得了白天的信息,您就可以在输出中使用它。试图隐藏时间但是在日期上进行分组会增加查询的复杂性,这可以通过用于UI的任何程序简单地解决。