2 kwooshung kwooshung 于 2014.01.25 15:57 提问

mysql查询如何先排序再分组呢?纠结了好几天了。

比如数据表“article”中有一组这样的数据:

id   uid    title
...  ....   .....
375   1     文章标题1
376   1     文章标题2
377   1     文章标题3
378   2     asdfasdf
379   3     fdaewqwe
...  ....   .....

然后我写了一句这样的sql:
select * from article order by id desc
执行后,结果如下:

id   uid    title
...  ....   .....
379   3     fdaewqwe
378   2     asdfasdf
377   1     文章标题3
376   1     文章标题2
375   1     文章标题1
...  ....   .....

然后我又加入了group by,为了只调用每个用户的1篇文章,sql代码如下
select * from article group by uid order by id desc
执行后,结果如下:

id   uid    title
...  ....   .....
379   3     fdaewqwe
378   2     asdfasdf
375   1     文章标题1
...  ....   .....

上面的数据看似正常,其实不对,因为先分组后排序了,所以我没法取得用户的最新文章了,始终是第一篇,正确的结果应该是:

id   uid    title
...  ....   .....
379   3     fdaewqwe
378   2     asdfasdf
377   1     文章标题3
...  ....   .....

这样才是取得用户的最新文章,并且过滤掉了用户的其他文章,因为如果页面上显示5条文章,不能有3条都是同一个人写的文章,应该这5条应该是最近发表文章的5个人的最新文章。

期间查询了很多技术资料,说用max或distinct的都不对,结果都是只显示第一篇文章。而且distnct更查询出来的结果顺序不对,更乱了。比如1,2,10,20,这几个id号变成了:

1
10
2
20

所以,想请教各路SQL大仙,看看应该怎么办呢?

当然,要求不能使用子查询。

10个回答

xinrongqiu
xinrongqiu   2014.01.25 18:08

SELECT S.* FROM (SELECT * FROM ARTICLE ORDER BY ID DESC ) S GROUP BY UID
试试这个 :把排完序后的数据作为临时表再分组

u014801324
u014801324 直接在 分组后面加排序 GROUP BY **** DESC
3 个月之前 回复
u012158739
u012158739 SELECT * FROM ( SELECT * FROM ARTICLE GROUP BY ID,UID ) t GROUP BY UID; 我是查询所有用户的首笔订单 他们的不行 这是我最终的解决办法
一年多之前 回复
qq245282209
qq245282209 这个事可以实现,但是效率上就不止是翻了一倍了.
大约 3 年之前 回复
kwooshung
kwooshung 额,不能用子查询哦
接近 4 年之前 回复
tlxzsz
tlxzsz   2014.01.26 15:54

select id,distinct uid,title from article group by uid order by id desc

GDC_laji
GDC_laji   2014.01.26 14:29

....难道所有的需求,一个select就能搞定

fyxxq
fyxxq   2014.05.30 14:13

不用子查询,目前好像没找到合适的解决方案。参考这篇文章:http://blog.sina.com.cn/s/blog_4a894d670100vdox.html

yan372397390
yan372397390   2016.08.20 09:58

CREATE TABLE test
(
str VARCHAR(1),
time DATETIME
);

INSERT INTO ywtg.test (str, time) VALUES ('a', '2016-08-03 16:41:37');
INSERT INTO ywtg.test (str, time) VALUES ('b', '2016-08-10 23:42:26');
INSERT INTO ywtg.test (str, time) VALUES ('a', '2016-08-13 23:42:46');
INSERT INTO ywtg.test (str, time) VALUES ('b', '2016-08-14 23:42:58');
INSERT INTO ywtg.test (str, time) VALUES ('b', '2016-08-15 23:43:13');
如上是表接口和数据,**需求:组与组之间按时间从大到小排序,组内数据按从小到大排序.**
如上数据也就是b组在a组前,b组和a组 组内数据又按从小到大排序,实现sql如下:

SELECT tt.*
FROM test tt LEFT JOIN (
SELECT
@rownum := @rownum + 1 AS rownum,
test.str
FROM (SELECT @rownum := 0) r, (SELECT str
FROM test
GROUP BY str
ORDER BY time DESC) test
) aa ON tt.str = aa.str
ORDER BY aa.rownum, time;

yan372397390
yan372397390   2016.08.20 09:59

CREATE TABLE test
(
str VARCHAR(1),
time DATETIME
);

INSERT INTO ywtg.test (str, time) VALUES ('a', '2016-08-03 16:41:37');
INSERT INTO ywtg.test (str, time) VALUES ('b', '2016-08-10 23:42:26');
INSERT INTO ywtg.test (str, time) VALUES ('a', '2016-08-13 23:42:46');
INSERT INTO ywtg.test (str, time) VALUES ('b', '2016-08-14 23:42:58');
INSERT INTO ywtg.test (str, time) VALUES ('b', '2016-08-15 23:43:13');
如上是表结构和数据,**需求:组与组之间按时间从大到小排序,组内数据按从小到大排序.**
如上数据也就是b组在a组前,b组和a组 组内数据又按从小到大排序,实现sql如下:

SELECT tt.*
FROM test tt LEFT JOIN (
SELECT
@rownum := @rownum + 1 AS rownum,
test.str
FROM (SELECT @rownum := 0) r, (SELECT str
FROM test
GROUP BY str
ORDER BY time DESC) test
) aa ON tt.str = aa.str
ORDER BY aa.rownum, time;

zpl19860102
zpl19860102   2016.09.22 15:51

select id,distinct uid,title from article order by id desc

yan372397390
yan372397390   2017.06.27 14:51

-- mysql分组排序:取每组时间最大的记录


-- Table structure for test


DROP TABLE IF EXISTS test;
CREATE TABLE test (
id int(11) DEFAULT NULL,
type varchar(255) DEFAULT NULL,
time datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


-- Records of test


INSERT INTO test VALUES ('1', '1', '2017-06-26 11:19:21');
INSERT INTO test VALUES ('2', '1', '2017-06-28 11:19:21');
INSERT INTO test VALUES ('3', '1', '2017-06-27 11:19:23');
INSERT INTO test VALUES ('4', '2', '2017-06-29 11:27:17');


-- 方式1


SELECT
t1.id,
t1.type,
t2.time
FROM
test t1
INNER JOIN (
SELECT
id,
MAX(time) time
FROM
test
GROUP BY
type
) t2 ON t1.id = t2.id;


-- 方式2,在mysql5.7以后版本不行


SELECT
*
FROM
(
SELECT
*
FROM
test
ORDER BY
time DESC
) t
GROUP BY
t.type;


-- 查看mysql版本


SELECT
version();

hyryysf
hyryysf   2017.08.09 11:07

SELECT MAX(id) AS max_id, uid, SUBSTRING_INDEX(GROUP_CONCAT(title ORDER BY id DESC) , ',', 1) AS new_title FROM article GROUP BY uid;

u014801324
u014801324   2017.10.27 18:01

你们什么回答啊,在分组后面写排序就可以了
GROUP BY **** DESC

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!