Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В. PHP на примерах (2 издание). Авторы: Кузнецов М.В., Симдянов И.В. Социальная инженерия и социальные хакеры. Авторы: Кузнецов М.В., Симдянов И.В. Программирование. Ступени успешной карьеры. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Хитрый запрос по сортировке групп строк в таблице...
 
 автор: Cyrax   (09.05.2009 в 20:50)   письмо автору
 
 

Что-то никак не соображу, как реализовать одним запросом следующую сортировку:
Имеется таблица table с полями id, name, type, price:

1 name1 1 25
2 name2 1 34
3 name3 1 10
4 name4 2 56
5 name5 2 70
6 name6 3 90
7 name7 3 86
8 name8 3 100
9 name9 4 10
10 name10 4 7

Задача нетривиальная. Необходимо провести сортировку по убыванию цены (price) не всей таблицы, а только в группах одного типа (type). При этом необходимо сохранить порядок таких групп.

Т.е. в результате необходимо получить:

2 name2 1 34
1 name1 1 25
3 name3 1 10
5 name5 2 70
4 name4 2 56
8 name8 3 100
6 name6 3 90
7 name7 3 86
9 name9 4 10
10 name10 4 7

Считать, что идентификаторы id (не PK) следуют в произвольном порядке. И для сохранения поряка следования групп эти идентификаторы можно и нужно использовать.

  Ответить  
 
 автор: Cyrax   (09.05.2009 в 21:05)   письмо автору
 
   для: Cyrax   (09.05.2009 в 20:50)
 

Группы тоже следуют в произвольном порядке, т.е. сначала может идти группа с type=3, затем type=1.
Т.е. GROUP BY type ASC, price DESC не сработает...

Одно из решений - ввести новое числовое или строковое поле, по которому и отсортировать всю таблицу. Для формирования значений этого поля нужно использовать id (для сохранения поряка следования групп) и значение поля price (для сортировки строк внутри групп). Собственно, задача на 40% уже решена...

Другое решение - ввести числовое поле type1 со следующими значениями:
1
1
1
2
2
3
3
3
4
4
Т.е. то же, что и type, но уже группы по этому полю идут по порядку. Далее пишем: GROUP BY type1 ASC, price DESC

  Ответить  
 
 автор: Trianon   (09.05.2009 в 21:15)   письмо автору
 
   для: Cyrax   (09.05.2009 в 20:50)
 

ORDER BY type ASC, price DESC 


про id не понял ни слова.

  Ответить  
 
 автор: Cyrax   (09.05.2009 в 21:17)   письмо автору
 
   для: Trianon   (09.05.2009 в 21:15)
 

2-й пост

  Ответить  
 
 автор: Trianon   (09.05.2009 в 21:18)   письмо автору
 
   для: Cyrax   (09.05.2009 в 21:17)
 

Во втором посту написана ересь.
Базы так не проектируют.

Если у Вас идентификатор группы сортирующими свойствами не обладает - значит следует завести таблицу этих самых групп. В которой описать порядок и прочие коошерные необходимые Вам свойства.

  Ответить  
 
 автор: Cyrax   (09.05.2009 в 21:21)   письмо автору
 
   для: Cyrax   (09.05.2009 в 21:17)
 

Вот пример получше:
Имеем:

3 name1 2 25
5 name2 2 34
4 name3 2 10
6 name4 4 56
7 name5 4 70
1 name6 1 90
10 name7 1 86
9 name8 1 100
2 name9 3 10
8 name10 3 7

Поле id - в произвольном порядке
Группы с одинаковыми type - тоже идут в произвольном порядке

Необходимо получить:
5 name2 2 34
3 name1 2 25
4 name3 2 10
7 name5 4 70
6 name4 4 56
9 name8 1 100
1 name6 1 90
10 name7 1 86
2 name9 3 10
8 name10 3 7

Порядок следования групп (2-4-1-3) необходимо сохранить.

  Ответить  
 
 автор: Cyrax   (09.05.2009 в 21:30)   письмо автору
 
   для: Cyrax   (09.05.2009 в 21:21)
 

>Если у Вас идентификатор группы сортирующими свойствами не обладает - значит следует завести таблицу этих самых групп.
> В которой описать порядок и прочие коошерные необходимые Вам свойства.

А с чего это группы должны сортирующим свойством обладать ?
В общем случае сортировка групп уже задана пользователем по каким-то определённым критериям. В соответствии с этими критериями и получена (налету) рассматриваемая таблица. Остаётся провести сортировку внутри групп.
Если необходимы какие-то вспомогательные таблицы, то лепим их во вложенных запросах.

  Ответить  
 
 автор: ~~   (09.05.2009 в 21:37)
 
   для: Cyrax   (09.05.2009 в 21:21)
 

> Поле id - в произвольном порядке
Тогда, простите, по какому критерию Вы отсортировали это:

Имеем:

3 name1 2 25
5 name2 2 34
4 name3 2 10
6 name4 4 56
7 name5 4 70
1 name6 1 90
10 name7 1 86
9 name8 1 100
2 name9 3 10
8 name10 3 7


?

У Вас нет ни одного поля по которому Вы сортируете, поэтому порядку "2-4-1-3" не откуда взяться.

  Ответить  
 
 автор: Cyrax   (09.05.2009 в 21:50)   письмо автору
 
   для: ~~   (09.05.2009 в 21:37)
 

>Тогда, простите, по какому критерию Вы отсортировали это...
>У Вас нет ни одного поля по которому Вы сортируете, поэтому порядку "2-4-1-3" не откуда взяться.

По некоторому полю (в примере не упоминается), значение которого одинаково для каждой группы.
Следующий ваш вопрос: избыточность данных.
Ответ: да, имеется. Но взамен я получаю возможность формирования и корректировки данных в Excel'е (далее просто формирую запросы на основе формул в отдельном столбце) в максимально простой и удобной форме. Т.е. на данный момент такая организация данных оптимальна. В дальнейшем - будет виднее.

  Ответить  
 
 автор: Cyrax   (09.05.2009 в 22:01)   письмо автору
 
   для: Cyrax   (09.05.2009 в 21:50)
 

В общем-то задача решена:
GROUP BY field ASC, price DESC
где field - поле, по которому отсортирована таблица )))

  Ответить  
 
 автор: Cyrax   (09.05.2009 в 22:08)   письмо автору
 
   для: Cyrax   (09.05.2009 в 22:01)
 

Хотя нет, не решена. Если я сортирую по идентификаторам (id), так не получится.
При сортировке по идентификаторам группы не разрушаются (остаются целыми), т.к. эта целостность обеспечивается на уровне Excel-таблицы.
Задача остаётся в силе.

  Ответить  
 
 автор: ~~   (09.05.2009 в 22:27)
 
   для: Cyrax   (09.05.2009 в 21:50)
 

Следующий ваш вопрос: избыточность данных.
Почему избыточность данных-то? Вы же только что признали, что отсортировать можно только по определённому полю, отвечающее за позицию, без него в представленном порядке сделать не выйдет (если, конечно, "2-4-1-3" не фиксированный порядок).

  Ответить  
 
 автор: Cyrax   (09.05.2009 в 23:00)   письмо автору
 
   для: ~~   (09.05.2009 в 22:27)
 

>Почему избыточность данных-то?

Для каждой группы каждое из двух полей (type и то, о котором я не упомянул в примере) имеет одинаковоее значения. По правилам нормальных форм следовало быввести ещё одну таблицу.

>Вы же только что признали, что отсортировать можно только по определённому полю, отвечающее за позицию, без него в
> представленном порядке сделать не выйдет (если, конечно, "2-4-1-3" не фиксированный порядок).

Отсортировать можно по любому полю, которое не нарушит целостность групп (все строки одной группы должны находится вместе).
Например, можно отсортировать по идентификатору (id) - целостность групп обеспечивается на уровне Excel-таблицы (в Excel-таблице идентификаторы идут по порядку, и группы идут по порядку). Но в этом случае конструкция ORDER BY id ASC, price DESC не будет работать, поскольку идентификаторы различны в пределах группы.

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

Этим условиям удовлетворяет, например, число, равное среднему значению идентификаторов внутри группы с округлением до целого:

id name type price новое_поле
0 name0 2 25 2
1 name1 2 34 2
2 name2 2 10 2
3 name3 4 56 5
4 name4 4 70 5
5 name5 1 90 7
6 name6 1 86 7
7 name7 1 100 7
8 name8 3 10 9
9 name9 3 7 9

И далее: ORDER BY новое_поле ASC, price DESC. При этом поля будут отсортированы по идентификаторам, а внутри групп - по убыванию цены.
Собственно, это и есть решение задачи.

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования