Неправильная сортировка mysql при group_by

Yura123

Новичок
Неправильная сортировка mysql при group_by

Есть таблица.
chapter_id varchar(100)
date date
time time

Данные следующие:

00000 2005-12-07 11:43:25
00001 2005-12-07 11:41:49
00001 2005-12-07 11:41:32
0000300001 2005-12-07 11:40:14
0000300001 2005-12-07 11:39:10
0000300001 2005-12-07 11:24:46
00007 2005-12-06 18:59:53
00000 2005-12-06 18:59:32

Делаю запрос:
SELECT chapter_id FROM stat_cms ORDER BY date DESC, time DESC LIMIT 0, 10

возвращаются строки с нормальной сортировкой по дате:

00000
00001
00001
0000300001
0000300001
0000300001
00007
00000

Естественно, мне не нужны дублирующие записи, потому пишу:

SELECT chapter_id FROM stat_cms GROUP BY chapter_id ORDER BY date DESC, time DESC LIMIT 0, 10

возвращается:

00001
0000300001
00007
00000

Обратите внимание, что запись со всеми нулями переместилась с первой позиции на последнюю.
Дальше еще интереснее.
Если заменить в таблице эти нули на 00002 или 00003, то все равно эта запись оказывается внизу результата.
Если же заменяем на 00004 и выше -- сортировка нормальная.

Где грабли?
 

alpine

Новичок
Короче ты гонишь - сортируешь по дате и спрашиваешь почему у тебя не сортирует по айди.
 

Yura123

Новичок
Читай внимательно.
Я сортирую по дате, мне и нужно сортировать по дате.
Но когда я убираю дубликаты айдишек (путем GROUP BY), то сортировка слетает.
Посмотри -- когда мы делаем простой запрос, то первой записью идет 00000, но когда мы убираем дубликаты, эта запись соскакивает вниз. Почему, ведь сортировка остается по дате, добавилась лишь группировка?
Если бы все было нормально, то запись 00000 осталась бы вверху.
 

tony2001

TeaM PHPClub
эти две строки ты объединил в одну:
00000 2005-12-06 18:59:32
00000 2005-12-07 11:43:25

вопрос: какая дата осталась?
 

Profic

just Profic (PHP5 BetaTeam)
Потому что в данном случае mysql волен оставить любую запись из диапазона. И какая именно вернется предугадать невозможно.
[sql]SELECT chapter_id, max(concat(`date`, ' ', `time`)) as max_datetime FROM stat_cms group by chapter_id ORDER BY max_datetime DESC[/sql]
Над запросом скорее всего нужно будет пошаманить. Главное - он отображает суть.
Да и иметь поля с именами равными ключевым словам SQL не есть хорошо.
 

Yura123

Новичок
Вот что отдает мускул:

00001 2005-12-07 11:41:49
0000300001 2005-12-07 11:40:14
00007 2005-12-06 18:59:53
00000 2005-12-06 18:59:32

Заметьте, что все записи взяты самые новые, т.к. с самой последней датой, кроме записи с нулями (00000).

-~{}~ 08.12.05 13:09:

Profic, большое спасибо, сработало.
Насчет ключевых слов мускул не ругается. Если что, их можно закавычить.
Еще раз всем спасибо.
 

alpine

Новичок
офтопик:
[sql]
SELECT VERSION()
[/sql]
4.0.18
[sql]
SHOW CREATE TABLE t
[/sql]
CREATE TABLE `t` (
`chapter_id` varchar(100) NOT NULL default '',
`date` date NOT NULL default '0000-00-00',
`time` time NOT NULL default '00:00:00'
) TYPE=MyISAM
INSERT INTO `t` VALUES ('00000', '2005-12-07', '11:43:25');
INSERT INTO `t` VALUES ('00001', '2005-12-07', '11:41:49');
INSERT INTO `t` VALUES ('00001', '2005-12-07', '11:41:32');
INSERT INTO `t` VALUES ('0000300001', '2005-12-07', '11:40:14');
INSERT INTO `t` VALUES ('0000300001', '2005-12-07', '11:39:10');
INSERT INTO `t` VALUES ('0000300001', '2005-12-07', '11:24:46');
INSERT INTO `t` VALUES ('00007', '2005-12-06', '18:59:53');
INSERT INTO `t` VALUES ('00000', '2005-12-06', '18:59:32');
[sql]
SELECT `chapter_id` FROM `t` GROUP BY `chapter_id` ORDER BY `date` , `time`
[/sql]
00007
0000300001
00001
00000
[sql]
SELECT `chapter_id` FROM `t` GROUP BY `chapter_id` ORDER BY `date` DESC, `time`DESC
[/sql]
00000
00001
0000300001
00007
 

Profic

just Profic (PHP5 BetaTeam)
Код:
mysql> select version();
+--------------+
| version()    |
+--------------+
| 5.0.13-rc-nt |
+--------------+
1 row in set (0.08 sec)

mysql> use test;
Database changed
mysql> CREATE TABLE `t` (
    -> `chapter_id` varchar(100) NOT NULL default '',
    -> `date` date NOT NULL default '0000-00-00',
    -> `time` time NOT NULL default '00:00:00'
    -> ) TYPE=MyISAM;
Query OK, 0 rows affected, 1 warning (0.45 sec)

mysql> INSERT INTO `t` VALUES ('00001', '2005-12-07', '11:41:49');
Query OK, 1 row affected (0.09 sec)

mysql> INSERT INTO `t` VALUES ('00001', '2005-12-07', '11:41:32');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO `t` VALUES ('0000300001', '2005-12-07', '11:40:14');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO `t` VALUES ('0000300001', '2005-12-07', '11:39:10');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO `t` VALUES ('0000300001', '2005-12-07', '11:24:46');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO `t` VALUES ('00007', '2005-12-06', '18:59:53');
Query OK, 1 row affected (0.00 sec)
[b]
mysql> INSERT INTO `t` VALUES ('00000', '2005-12-06', '18:59:32');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO `t` VALUES ('00000', '2005-12-07', '11:43:25');
Query OK, 1 row affected (0.00 sec)
[/b]
mysql> SELECT `chapter_id`
    -> FROM `t`
    -> GROUP BY `chapter_id`
    -> ORDER BY `date` , `time`;
+------------+
| chapter_id |
+------------+
| 00000      |
| 00007      |
| 0000300001 |
| 00001      |
+------------+
4 rows in set (0.06 sec)

mysql> SELECT `chapter_id`
    -> FROM `t`
    -> GROUP BY `chapter_id`
    -> ORDER BY `date` DESC , `time` DESC;
+------------+
| chapter_id |
+------------+
| 00001      |
| 0000300001 |
| 00007      |
| 00000      |
+------------+
4 rows in set (0.00 sec)

mysql>
 

Yura123

Новичок
У меня 4.1.14 версия, но запрос

SELECT `chapter_id`
FROM `t`
GROUP BY `chapter_id`
ORDER BY `date` DESC , `time` DESC

пишет 00000 в конце.
 

Profic

just Profic (PHP5 BetaTeam)
alpine
Это я к тому, что такой запрос нестабилен. Т.е. зависит от того в каком порядке вносились данные в таблицу (выделено болдом). Кстати, подобные запросы вообще-то не являются валидными. Насколько я знаю, только MySQL такое позволяет, а остальные РСУБД просто пошлют на три буквы, сказав, что для сортировки используется поле, которое не учавствует в агррегатных операциях.
 
Сверху