Mysql ORDER BY или MAX () для нескольких полей таблицы orderring? - PullRequest
3 голосов
/ 07 июня 2011

Я перепутал странное поведение запроса MySQL.У меня есть следующий запрос MySQL:

SELECT 'username','status', 'field_1', 'field_2', 'field_3', 'field_4',  
    FROM my_table 
    ORDER by field_1 DESC, field_2 DESC, field_3 DESC, field_4 DESC 
    LIMIT 0,10 

По идее, он должен упорядочить 10 строк в порядке убывания в зависимости от того, сколько полей значений имеют в условии ORDER BY.Но в результате я получаю следующее:

Кейт 103
Пит 101
Стив 102

вместо

Кейт 103
Стив 102
Пит 101

Кто-нибудь знает, почему он установил неправильный порядок?И что делать, чтобы сделать правильное условие ORDER BY DESC?

Можно ли использовать MAX () для нескольких полей?Если да, то возможно ли организовать запрос MySQL следующим образом?

SELECT 'username','status', 'field_1', 'field_2', 'field_3', 'field_4', MAX(field_1,field_2,field_3,field_4) AS total 
    FROM my_table 
    ORDER by total DESC 
    LIMIT 0,10

Ответы [ 2 ]

11 голосов
/ 08 июня 2011

Вы не можете использовать MAX(), потому что эта функция возвращает наибольшее значение в одном столбце во многих строках. Но вы можете использовать функцию MySQL GREATEST(). Это возвращает самый большой из его аргументов, которые все приходят из одной строки.

SELECT `username`, `status`, GREATEST(field_1,field_2,field_3,field_4) AS field_greatest
FROM my_table
ORDER BY field_greatest DESC
LIMIT 0,10

Но я бы также прокомментировал, что вы нарушили 1-ую нормальную форму , сохранив несколько столбцов, которые должны быть одного и того же «вида» данных. Это называется повторяющиеся группы . В результате вы сталкиваетесь с этим хлопотным запросом. Также вам нужно будет переписать все ваши запросы, когда вы добавите пятое поле.

Вместо этого создайте вторую таблицу и сохраните все «поля» в одном столбце со ссылкой на пользователя. Тогда вы можете присоединиться к столам:

SELECT t.username, t.status, f.field
FROM my_table AS t
LEFT OUTER JOIN (SELECT username, MAX(field) AS field FROM my_fields GROUP BY username) AS f
  ON t.username = f.username
ORDER BY f.field DESC
LIMIT 0,10

Или мой любимый способ получить строку с наибольшим значением для группы:

SELECT t.username, t.status, f1.field
FROM my_table AS t
JOIN my_fields AS f1 ON t.username = f1.username
LEFT OUTER JOIN my_fields AS f2 ON t.username = f2.username AND f1.field < f2.field
WHERE f2.username IS NULL
ORDER BY f1.field DESC
LIMIT 0,10
0 голосов
/ 08 июня 2011

Нельзя вводить несколько значений в макс.Вы можете сделать несколько вложенных IF().

SELECT `username`,`status`,  
MAX(
  if( field_1 > field_2 and field_1 > field_3 and field_1 > field_4 ,field_1, 
  if( field_2 > field_3 and field_2 > field_4 ,field_2,
  if( field_3 > field_4, field_3, field_4 )))) AS total 
FROM my_table 
ORDER by total DESC 
LIMIT 0,10
...