Php 请帮助我建立这个查询

Php 请帮助我建立这个查询,php,mysql,group-by,join,greatest-n-per-group,Php,Mysql,Group By,Join,Greatest N Per Group,我想按rls_id提取组的行,但要使用最新/最近的日期 上面的查询很好,但我不想使用子查询。我需要别的办法 CREATE TABLE IF NOT EXISTS `tbl_revisions` ( `id` int(21) NOT NULL AUTO_INCREMENT, `rls_id` int(21) NOT NULL, `date` datetime NOT NULL, `user` int(21) NOT NULL, `data` blob NOT NULL,

我想按rls_id提取组的行,但要使用最新/最近的日期

上面的查询很好,但我不想使用子查询。我需要别的办法

CREATE TABLE IF NOT EXISTS `tbl_revisions` 
(
  `id` int(21) NOT NULL AUTO_INCREMENT,
  `rls_id` int(21) NOT NULL,
  `date` datetime NOT NULL,
  `user` int(21) NOT NULL,
  `data` blob NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=66 ;
编辑:需要一种更快的方式

好的。多亏了@Bill Karwin和@OMG Ponies,我得到了两个工作查询

我在这里粘贴这两个问题的解释,这样其他人会学得更好

Bill Karwin :

SELECT r1.*
FROM `tbl_revisions` r1
LEFT OUTER JOIN `tbl_revisions` r2
  ON (r1.`rls_id` = r2.`rls_id` AND r1.`date` < r2.`date`)
WHERE r2.`rls_id` IS NULL;
试试这个:

SELECT * FROM tbl_revisions WHERE date = MAX(date) FROM tbl_revisions GROUP BY rls_id;

老实说,我还没有尝试过这个,但是试一试。

不使用子查询?好:

SELECT t.* 
  FROM TBL_REVISIONS t
  JOIN (SELECT rls_id,
               MAX(date) AS max_date
          FROM TBL_REVISIONS
      GROUP BY rls_id) x ON x.rls_id = t.rls_id
                        AND x.max_date = t.date
有些人可能称之为subselect,但更准确地说,x是派生表或内联视图。Subselect通常是SELECT子句本身中的SELECT语句,如:

SELECT ...,
       (SELECT COUNT(*)...)

无论如何,请检查标签beaster-n-per-group以了解其他各种示例。

此场景在MySQL站点上表示为“groupwise max”问题。看起来OMG Ponies做得很好-没有任何子查询,你不可能成功,但OMG Ponies的JOIN ed版本使用了一个不相关的子查询,这更有效:

SELECT r1.*
FROM `tbl_revisions` r1
LEFT OUTER JOIN `tbl_revisions` r2
  ON (r1.`rls_id` = r2.`rls_id` AND r1.`date` < r2.`date`)
WHERE r2.`rls_id` IS NULL;

我已经试过了,比较起来不能使用MAX函数,所以没有工作编辑不工作,返回了错误的结果。当我运行我的查询时,它返回2,但这个查询是空的。我看不出这比带子查询的查询快。@Arsheep:抱歉,我在WHERE子句中犯了一个错误。它应该是r2.rls_id为null的位置,而不是r1。用我的编辑试试。@Kendall:如果你在评论中建议在rls_id,date上定义一个复合索引,这会非常快。表中还有其他键吗?您可能受益于在rls_id上添加多列索引,date.BTW,此查询是不明确的,因为您将通过rls_id从聚合数据组中获取非聚合列*。这可能会在MYSQL中出现,但在其他SQL数据库(如postgresql)中,将调用您。
SELECT ...,
       (SELECT COUNT(*)...)
SELECT r1.*
FROM `tbl_revisions` r1
LEFT OUTER JOIN `tbl_revisions` r2
  ON (r1.`rls_id` = r2.`rls_id` AND r1.`date` < r2.`date`)
WHERE r2.`rls_id` IS NULL;