通过 JOIN 和 GROUP BY 获取最近的行?
Posted
技术标签:
【中文标题】通过 JOIN 和 GROUP BY 获取最近的行?【英文标题】:Getting the recent row by JOIN & GROUP BY? 【发布时间】:2016-04-27 07:16:54 【问题描述】:这是表album
,它的结构和数据是,
这是另一个表photos
,它的结构和数据是,
我想列出所有相册名称、相应相册的总照片、按 JOIN 和 GROUP BY 上传的最后一张图片。
这是我现在使用的 Codeigniter 查询。一切正常,除了它获取image
列值的第一行而不是最新行。
$query = $this->db->select('albums.name, photos.image, albums.created, albums.id,
COUNT(photos.id) as total')
->from('photos')
->join('albums', 'albums.id = photos.album_id')
->order_by('photos.id', 'desc')
->group_by('photos.album_id')
->limit($limit, $offset)
->get();
上面生成的 SQL 查询是,
SELECT `albums`.`name`, `photos`.`image`, `albums`.`created`, `albums`.`id`, COUNT(photos.id) as total FROM `photos` JOIN `albums` ON `albums`.`id` = `photos`.`album_id` GROUP BY `photos`.`album_id` ORDER BY `photos`.`id` DESC LIMIT 10
对于这两个查询,结果都是,
["名称":"电影 Stills","image":"assets/images/albums/2016/01/84786b91857b45fa9391943e9a468ac6.jpg","created":"2016-01-19 23:41:53","id":"3","total":"3","name":"Firstlook","image":"assets/images/albums/2016/01/6e90cdfdec444dfc53f4a7c30a2ac31e。 jpg","创建":"2016-01-19 23:16:05","id":"1","total":"2"]
如果您查看图像键,它会显示第一个而不是最后一行的值。
我对这两种查询解决方案(Codeigniter/SQL)都持开放态度。
【问题讨论】:
从相册表中加入照片表 也许这个答案可以帮助你***.com/questions/15390303/how-to-group-by-desc-order @K1N6 有整数类型的列。在这里,它的字母数字。所以,MAX 不起作用。 【参考方案1】:$query = $this->db->select('albums.name, ph.image, albums.created, albums.id,
COUNT(ph.id) as total')
->from('photos as ph') // added prefix
->join('albums', 'albums.id = ph.album_id')
->where('ph.id = (SELECT MAX(ph1.id) FROM photos as ph1 WHERE ph1.album_id=ph.album_id)',NULL,FALSE) // subquery to get latest record
->order_by('ph.id', 'desc')
->group_by('ph.album_id')
->limit($limit, $offset)
->get();
where() 中的 NULL,FALSE 告诉 CodeIgniter
不要逃避查询,这可能会搞砸 Sub query in CodeIgniter
或者,SQL 查询是
SELECT `albums`.`name`, `ph`.`image`, `albums`.`created`, `albums`.`id`, COUNT(ph.id) as total FROM `photos` as `ph` JOIN `albums` ON `albums`.`id` = `ph`.`album_id` WHERE ph.id IN (SELECT MAX(ph1.id) FROM photos as ph1 WHERE ph1.album_id=ph.album_id) GROUP BY `ph`.`album_id` ORDER BY `ph`.`id` DESC LIMIT 10
【讨论】:
You have an error in your SQL syntax; check the manual that corresponds to your mysql server version for the right syntax to use near 'as
ph1 在哪里 ph1.
album_id=ph.
album_id) GROUP BY
ph.
album_id` 订购' at line 4
顺便说一句,我主要需要获取最新的image
值。
感谢您的询问。我只需要在WHERE
条件中添加一些额外的参数即可工作。
@user3289108 欢迎您,我已经运行了我的查询,但它工作正常。很高兴能帮到你!
在您的回答中查看我的编辑。可能是 Codeigniter V3 有一个严格的条件。【参考方案2】:
您按photos
.album_id
分组,但创建的日期字段不受 agrregate 函数的约束,因此 mysql 根据文档获取随机行的值(好吧,它不是那么随机,它拾取它在扫描数据时遇到的第一个对应值)
在创建的日期字段上使用 max() 来检索最新日期:
SELECT max(`albums`.`name`) as name, `photos`.`image`, max(`albums`.`created`) as latest_date, `albums`.`id`, COUNT(photos.id) as total
FROM `photos` JOIN `albums` ON `albums`.`id` = `photos`.`album_id`
GROUP BY `photos`.`album_id`
ORDER BY `photos`.`id` DESC LIMIT 10
photos
.image
也会遇到同样的问题。要获取与最新创建日期相关联的图像,您需要一个子查询。
select a.name, p.image, t.mdate
from albums a
inner join (select album_id, max(created_date) as mdate from photos group by album_id) t on a.id=t.album_id
inner join photos p on a.id=p.album_id and t.mdate=p.created_date
【讨论】:
谢谢,但我唯一担心的是最近收到image
。如何使用子查询实现?
空结果。顺便说一句,它是created
而不是created_date
。你需要我的东西,我可以给你。
向我提供您运行的确切查询。您可能混淆了联接中的日期列
你能帮忙吗?我无法得到。
@Strawberry 也许你可以提供一些关于它有什么问题的指针。我能看到的唯一改进的地方是使用 max(photo.id) 而不是 max(created) 对子查询进行连接。但是,据我所知,即使当前版本也应该通过album_id返回最新照片的详细信息,前提是相册至少有1张对应的图片。【参考方案3】:
经过多次尝试,我找到了解决问题的方法。这是一个简单的查询,
$query = $this->db->query("SELECT p.`image`, COUNT(p.`id`) as total, a.`id`, a.`created`, a.`name` FROM `albums` as a JOIN (SELECT * FROM `photos` as p1 ORDER BY id DESC) p ON a.`id` = p.`album_id` GROUP BY p.`album_id` ORDER BY p.`id` DESC LIMIT 10");
我使用了@Shadow 所说的子查询,我只是对子查询的列Id
进行了 ORDER BY。通过这个,一切都按预期工作。
【讨论】:
当你不使用完整分组或代码迁移到需要完整分组的mysql服务器时,当mysql默默地改变它的行为时,你会惊讶为什么你的代码不工作。以上是关于通过 JOIN 和 GROUP BY 获取最近的行?的主要内容,如果未能解决你的问题,请参考以下文章