我有以下数据库结构:
网站表
id | name | other_fields
备份表
id | site_id | initiated_on(unix timestamp) | size(float) | status
所以Backups
表格与Sites
表之间存在多对一关系site_id
我想以下列格式输出数据
name | Latest initiated_on | status of the latest initiated_on row
我有以下SQL查询
SELECT *, `sites`.`id` as sid, SUM(`backups`.`size`) AS size
FROM (`sites`)
LEFT JOIN `backups` ON `sites`.`id` = `backups`.`site_id`
WHERE `sites`.`id` = '1'
GROUP BY `sites`.`id`
ORDER BY `backups`.`initiated_on` desc
问题是,通过上面的查询,我可以实现我正在寻找的东西,但唯一的问题是我没有得到最新的initiated_on
值。
因此,如果backups
中有site_id
= 1
的3行,则查询不会选择initiated_on
中值最高的行。它只是挑出任何一行。
请帮忙,
提前感谢。
答案 0 :(得分:2)
你应该尝试:
SELECT sites.name, FROM_UNIXTIME(b.latest) as latest, b.size, b.status
FROM sites
LEFT JOIN
( SELECT bg.site_id, bg.latest, bg.sizesum AS size, bu.status
FROM
( SELECT site_id, MAX(initiated_on) as latest, SUM(size) as sizesum
FROM backups
GROUP BY site_id ) bg
JOIN backups bu
ON bu.initiated_on = bg.latest AND bu.site_id = bg.site_id
) b
ON sites.id = b.site_id
在此处的GROUP BY
子查询 - bg
中,您可以用于SELECT
的唯一列是由函数聚合或列在{{1}中的列部分。
http://dev.mysql.com/doc/refman/5.5/en/group-by-hidden-columns.html
获得所有汇总值后,您需要再次将结果加入GROUP BY
,以查找具有最新时间戳的行的其他值 - backups
。
最后将结果加入b
表以获取名称 - 如果要列出所有网站,即使没有备份,也可以离开加入。
答案 1 :(得分:1)
试试这个:
select S.name, B.initiated_on, B.status
from sites as S left join backups as B on S.id = B.site_id
where B.initiated_on =
(select max(initiated_on)
from backups
where site_id = S.id)
答案 2 :(得分:1)
要获取最新时间,您需要创建一个这样的子查询:
SELECT sites.id as sid,
SUM(backups.size) AS size
latest.time AS latesttime
FROM sites AS sites
LEFT JOIN (SELECT site_id,
MAX(initiated_on) AS time
FROM backups
GROUP BY site_id) AS latest
ON latest.site_id = sites.id
LEFT JOIN backups
ON sites.id = backups.site_id
WHERE sites.id = 1
GROUP BY sites.id
ORDER BY backups.initiated_on desc
我已经删除了SELECT *,因为这只能使用MySQL,无论如何通常都是不好的做法。如果包含其他字段,非MySQL RDBS会抛出错误,甚至是单独的,您需要将此查询本身放入子查询中,然后对sites表执行INNER JOIN以获取其余字段。这是因为他们将尝试将所有这些添加到GROUP BY语句中,如果您有长文本字段,则会失败(或者至少非常慢)。