通过JOIN&获取最近的一行通过...分组?

时间:2016-01-21 06:46:49

标签: php mysql sql codeigniter

这是表格album,其结构和数据是

enter image description here

这是另一个表photos,它的结构和数据是

enter image description here

我想列出所有相册名称,相应相册的总照片,上次上传的图片由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

对于查询结果都是,

  

[{"名称":"电影   剧照""图像":"资产/图像/专辑/ 2016/01 / 84786b91857b45fa9391943e9a468ac6.jpg""创建":" 2016- 01-19   23:41:53"" ID":" 3""总":" 3"},{&#34 ;名称":" FirstLook以""图像":"资产/图像/专辑/ 2016/01 / 6e90cdfdec444dfc53f4a7c30a2ac31e.jpg""创建与#34;:" 2016年1月19日   23:16:05"" ID":" 1""总":" 2"}]

如果查看图像键,则显示第一行而不是最后一行的值。

我可以同时使用任何一种查询解决方案(Codeigniter / SQL)。

3 个答案:

答案 0 :(得分:2)

您正在按photosalbum_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

photosimage会遇到同样的问题。要获取与最新创建日期关联的图像,您需要一个子查询。

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

答案 1 :(得分: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 Query是

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

答案 2 :(得分:-1)

经过多次尝试,我得到了解决问题的方法。这是简单的查询,

$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。通过这一切,一切都按预期工作。