通过 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 获取最近的行?的主要内容,如果未能解决你的问题,请参考以下文章

使用 MySQL 通过 JOIN 获取 GROUP BY 中的 SUM

使用 group by 和 Laravel 获取最新行

数据库的group 和group by 的用法?

带有 MAX() 的 GROUP BY 返回错误的行 ID

从 GROUP BY 中获取具有 NULL 列的行

使用“group by”获取正确的行值 [重复]