比如数据表“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大仙,看看应该怎么办呢?
当然,要求不能使用子查询。
....难道所有的需求,一个select就能搞定
select id,distinct uid,title from article group by uid order by id desc
不用子查询,目前好像没找到合适的解决方案。参考这篇文章:http://blog.sina.com.cn/s/blog_4a894d670100vdox.html
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;
-- 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();
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;
SELECT S.* FROM (SELECT * FROM ARTICLE ORDER BY ID DESC ) S GROUP BY UID
试试这个 :把排完序后的数据作为临时表再分组
select id,distinct uid,title from article order by id desc
你们什么回答啊,在分组后面写排序就可以了
GROUP BY **** DESC