设为首页收藏本站

自学it网-公益PHP培训!

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 981|回复: 2

[未解决] from型 子查询 的讨论 [复制链接]

Rank: 1

发表于 2017-3-7 08:29:22 |显示全部楼层
本帖最后由 mich2016 于 2017-3-7 08:31 编辑

感谢十八哥mysql视频,非常强大。不过学习上,遇到了子查询的问题,提出来和大家探讨。

用where 和 from 子查询分别求出goods表的每个栏目(cat_id)下 的最新的商品(goods_id值最大):where子查询没有问题,也好理解,但from子查询出了问题:

where子查询(正确结果):

select goods_id, goods_name,cat_id from goods where goods_id in (select max(goods_id) from goods group by cat_id) order by cat_id;
+----------+----------------------------------------+--------+
| goods_id | goods_name                             | cat_id |
+----------+----------------------------------------+--------+
|       16 | 恒基伟业g101                           |      2 |
|       32 | 诺基亚n85                              |      3 |
|       18 | 夏新t5                                 |      4 |
|       23 | 诺基亚n96                              |      5 |
|        7 | 诺基亚n85原装立体声耳机hs-82           |      8 |
|        6 | 胜创kingmax内存卡                      |     11 |
|       26 | 小灵通/固话20元充值卡                  |     13 |
|       30 | 移动20元充值卡                         |     14 |
|       28 | 联通50元充值卡                         |     15 |
+----------+----------------------------------------+--------+

from型子查询(错误结果):结果很奇怪,除了cat_id=8,goods_id取的是中间的一个值外(有3,4,7三值,实际取的是4)。其它cat_id时,goods_id全是取的最小值。(把括号子查询的desc换成asc,结果一样)。

SELECT * FROM (SELECT goods_id, cat_id, goods_name FROM goods ORDER BY cat_id asc, goods_id desc) as tmp GROUP BY cat_id;

+----------+--------+-----------------------+
| goods_id | cat_id | goods_name            |
+----------+--------+-----------------------+
|       16 |      2 | 恒基伟业g101          |
|        8 |      3 | 飞利浦9@9v            |
|        1 |      4 | kd876                 |
|       23 |      5 | 诺基亚n96             |
|        4 |      8 | 诺基亚n85原装充电器   |
|        5 |     11 | 索爱原装m2卡读卡器    |
|       25 |     13 | 小灵通/固话50元充值卡 |
|       29 |     14 | 移动100元充值卡       |
|       27 |     15 | 联通100元充值卡       |
+----------+--------+-----------------------+

为了检验是不是语句的错误,我把上面 from型子查询 的长句子分开:括号内部分先查询并另存成一个表 XXX,然后从 XXX 查询 goods_id的最大值,查询的结果是正确的(和上面 where型子查询一样):

CREATE TABLE xxx as SELECT goods_id, cat_id, goods_name FROM goods ORDER BY cat_id asc, goods_id desc;

SELECT * FROM xxx GROUP BY cat_id order by cat_id;

mysql> SELECT * FROM xxx GROUP BY cat_id order by cat_id;

+----------+--------+----------------------------------------+
| goods_id | cat_id | goods_name                             |
+----------+--------+----------------------------------------+
|       16 |      2 | 恒基伟业g101                           |
|       32 |      3 | 诺基亚n85                              |
|       18 |      4 | 夏新t5                                 |
|       23 |      5 | 诺基亚n96                              |
|        7 |      8 | 诺基亚n85原装立体声耳机hs-82           |
|        6 |     11 | 胜创kingmax内存卡                      |
|       26 |     13 | 小灵通/固话20元充值卡                  |
|       30 |     14 | 移动20元充值卡                         |
|       28 |     15 | 联通50元充值卡                         |
+----------+--------+----------------------------------------+

搜了一下,本自学网上有人说是mysql版本的问题mysql5.5之后的版本中使用 from子查询 会有此问题。(见:http://www.zixue.it/thread-19736-1-1.html ) 但不知这个说法是否可靠,有没有其他人遇到过同样的问题?

另外,我用了2种mysql,结果一样。

1,MySQL 社区版本,5.7.9。
2,XAMPP,10.1.19-MariaDB。

附:goods原表(为方便起见,我把它order by了):

mysql> SELECT goods_id,goods_name,cat_id FROM goods ORDER BY cat_id, goods_id DESC;
+----------+----------------------------------------+--------+
| goods_id | goods_name                             | cat_id |
+----------+----------------------------------------+--------+
|       16 | 恒基伟业g101                           |      2 |
|       32 | 诺基亚n85                              |      3 |
|       31 | 摩托罗拉e8                             |      3 |
|       24 | p806                                   |      3 |
|       22 | 多普达touch hd                         |      3 |
|       21 | 金立 a30                               |      3 |
|       20 | 三星bc01                               |      3 |
|       19 | 三星sgh-f258                           |      3 |
|       17 | 夏新n7                                 |      3 |
|       15 | 摩托罗拉a810                           |      3 |
|       13 | 诺基亚5320 xpressmusic                 |      3 |
|       12 | 摩托罗拉a810                           |      3 |
|       11 | 索爱c702c                              |      3 |
|       10 | 索爱c702c                              |      3 |
|        9 | 诺基亚e66                              |      3 |
|        8 | 飞利浦9@9v                             |      3 |
|       18 | 夏新t5                                 |      4 |
|       14 | 诺基亚5800xm                           |      4 |
|        1 | kd876                                  |      4 |
|       23 | 诺基亚n96                              |      5 |
|        7 | 诺基亚n85原装立体声耳机hs-82           |      8 |
|        4 | 诺基亚n85原装充电器                    |      8 |
|        3 | 诺基亚原装5800耳机                     |      8 |
|        6 | 胜创kingmax内存卡                      |     11 |
|        5 | 索爱原装m2卡读卡器                     |     11 |
|       26 | 小灵通/固话20元充值卡                  |     13 |
|       25 | 小灵通/固话50元充值卡                  |     13 |
|       30 | 移动20元充值卡                         |     14 |
|       29 | 移动100元充值卡                        |     14 |
|       28 | 联通50元充值卡                         |     15 |
|       27 | 联通100元充值卡                        |     15 |
+----------+----------------------------------------+--------+


谢谢。(第一次发帖)

使用道具 举报

Rank: 1

发表于 2017-5-26 15:29:06 |显示全部楼层
SELECT * FROM (SELECT goods_id, cat_id, goods_name FROM goods ORDER BY cat_id asc, goods_id desc) as tmp GROUP BY cat_id;

group by某个字段的时候如果是降序(或者升序) 只会取到排序的字段的最大值或者最小值,不会取到对应这个最大值或者最小值的记录的其他字段的内容的。你这样在from里面排序在外面group by基本是没用的
这样的查询我一般都是用连接来处理的。

使用道具 举报

Rank: 1

发表于 2018-4-14 16:16:21 |显示全部楼层

应该是MySQL版本的问题,我用的5.7.20版,也遇到了这个问题。网上查资料才知道,
在5.7版本中order by 要想在内层查询中起作用,就必须和limit同时使用。可以用如下方式:

select * from (select goods_id,cat_id,goods_name from goods order by goods_id desc limit 32) as t group by cat_id,

MySQL虽然支持这样写,但从语义上来说,这种写法是说不通的,不够规范。

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

Archiver|自学it网 ( 京ICP备12009156号 )  

GMT+8, 2018-4-25 00:35 , Processed in 0.029570 second(s), 5 queries , Memcache On.

Powered by Discuz! X2

© 2001-2011 Comsenz Inc.

回顶部