Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: Сортировка объедененных таблиц

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


 Страниц (1): [1]   

> Без описания
DlTA
Отправлено: 21 Августа, 2015 - 14:25:42
Post Id



Постоянный участник


Покинул форум
Сообщений всего: 2952
Дата рег-ции: Окт. 2010  


Помог: 53 раз(а)




имеем мускуль

пересекаются 3 таблицы
товары, наличие, поставщики
товар: (id, ....)
наличие: (id, товарID, поставщикID, ...)
поставщики: (id, pos, ...)

в выборке мне нужно чтоб товары сортировались по позиции поставщика (поле pos)

ORDER BY `whouses`.`pos` ASC

но вот результат меня удивил

делаю первый запрос с выборкой
CODE (SQL):
скопировать код в буфер обмена
  1. SELECT DISTINCT goods.id , `whouses`.`pos`
  2. ...
  3. ORDER BY `whouses`.`pos` ASC

результат:
Спойлер (Отобразить)

вроде все верно

теперь выборка чисто товаров,
CODE (SQL):
скопировать код в буфер обмена
  1. SELECT DISTINCT goods.id
  2. ...
  3. ORDER BY `whouses`.`pos` ASC

Спойлер (Отобразить)

и вот тут обращаем внимание на последний в списке 'id' => '38529'
в первой выборке отчетливо видно что для данного товара есть позиция поставщика 0
хотя так же есть и позиция 40
но почему выборка такая странная, и как мне получить корректную?
 
 Top
DeepVarvar Супермодератор
Отправлено: 21 Августа, 2015 - 14:48:46
Post Id



Активный участник


Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008  
Откуда: Альфа Центавра


Помог: 353 раз(а)




Убери DISTINCT и сделай GROUP BY
 
 Top
DlTA
Отправлено: 21 Августа, 2015 - 14:58:04
Post Id



Постоянный участник


Покинул форум
Сообщений всего: 2952
Дата рег-ции: Окт. 2010  


Помог: 53 раз(а)




DeepVarvar пишет:
Убери DISTINCT и сделай GROUP BY

не знаю чем бы это мне могло помочь, результат так же плох
 
 Top
DeepVarvar Супермодератор
Отправлено: 21 Августа, 2015 - 15:29:35
Post Id



Активный участник


Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008  
Откуда: Альфа Центавра


Помог: 353 раз(а)




Ну тогда скинь запросы полность, ато не очень понятно что в них за магия у тебя.
 
 Top
DlTA
Отправлено: 21 Августа, 2015 - 15:41:38
Post Id



Постоянный участник


Покинул форум
Сообщений всего: 2952
Дата рег-ции: Окт. 2010  


Помог: 53 раз(а)




весь запрос
Спойлер (Отобразить)


4-я таблица hierarchy тут для фильтра
 
 Top
DeepVarvar Супермодератор
Отправлено: 21 Августа, 2015 - 15:48:30
Post Id



Активный участник


Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008  
Откуда: Альфа Центавра


Помог: 353 раз(а)




Да, понял в чем трабла. Тебе надо сделать с подзапросом -- сначала отсортировать, а уже потом группировать, тогда в группировку попадут те, которые более подходят, ибо они будут выше из-за сортировки.
(Добавление)
Типа:

CODE (SQL):
скопировать код в буфер обмена
  1. SELECT srt.*
  2.     FROM (
  3.         SELECT * FROM tbl ORDER BY sortable_field ASC
  4.     ) srt
  5.     GROUP BY srt.groupable_field
 
 Top
DlTA
Отправлено: 21 Августа, 2015 - 16:10:26
Post Id



Постоянный участник


Покинул форум
Сообщений всего: 2952
Дата рег-ции: Окт. 2010  


Помог: 53 раз(а)




DeepVarvar пишет:
Тебе надо сделать с подзапросом -- сначала отсортировать, а уже потом группировать


CODE (SQL):
скопировать код в буфер обмена
  1. SELECT DISTINCT id
  2. FROM
  3.         (
  4.         SELECT DISTINCT `goods`.`id` AS id , `whouses`.`pos` AS pos
  5.         ...    
  6.         ORDER BY `whouses`.`pos` ASC
  7. ) AS tab


да, так оно работает, но почему оно не работает без использования подзапроса??
 
 Top
DeepVarvar Супермодератор
Отправлено: 21 Августа, 2015 - 16:17:34
Post Id



Активный участник


Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008  
Откуда: Альфа Центавра


Помог: 353 раз(а)




Потому что сортировку он делает уже после группировки, а группировка уже оставила только ПЕРВЫЕ попавшиеся.
 
 Top
Мелкий Супермодератор
Отправлено: 21 Августа, 2015 - 16:19:17
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




Потому что distinct (как и group by, собственно) работают до сортировки.
Раз до сортировки - значит обрабатывают неупорядоченное множество, следовательно хватают любую первую подходящую строку.

Без подзапроса используйте группировку и функции аггрегации min или max по значению pos (путал, путаю и буду путать asc/desc Ниндзя )


-----
PostgreSQL DBA
 
 Top
DlTA
Отправлено: 21 Августа, 2015 - 16:19:27
Post Id



Постоянный участник


Покинул форум
Сообщений всего: 2952
Дата рег-ции: Окт. 2010  


Помог: 53 раз(а)




DeepVarvar пишет:
Потому что сортировку он делает уже после группировки, а группировка уже оставила только ПЕРВЫЕ попавшиеся.

любопытная фича/баг, надо помануалить
 
 Top
DeepVarvar Супермодератор
Отправлено: 21 Августа, 2015 - 16:21:18
Post Id



Активный участник


Покинул форум
Сообщений всего: 10377
Дата рег-ции: Дек. 2008  
Откуда: Альфа Центавра


Помог: 353 раз(а)




Мелкий пишет:
Без подзапроса используйте группировку и функции аггрегации min или max по значению pos
Оно оптимальнее будет чем подзапрос?
 
 Top
DlTA
Отправлено: 21 Августа, 2015 - 16:21:57
Post Id



Постоянный участник


Покинул форум
Сообщений всего: 2952
Дата рег-ции: Окт. 2010  


Помог: 53 раз(а)




Мелкий пишет:
Без подзапроса используйте группировку и функции аггрегации min или max по значению pos

а как такое чудо будет в итоге выглядеть?
 
 Top
Мелкий Супермодератор
Отправлено: 21 Августа, 2015 - 16:37:09
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




DeepVarvar пишет:
Оно оптимальнее будет чем подзапрос?

Не знаю, это просто правильнее с точки зрения SQL.
По идее, для группировки хватит одной временной таблицы, а для подзапроса - самому подзапросу временная таблица, затем distinct наверняка себе ещё одну временную таблицу сделает.

Выглядит как-то так:
CODE (SQL):
скопировать код в буфер обмена
  1. SELECT goods.id, min(`whouses`.`pos`)
  2. FROM
  3.         `goods`
  4.         JOIN `hierarchy` ON `hierarchy`.`intableID`=`goods`.`id` AND `hierarchy`.parent = '21255' AND `hierarchy`.`tableID` = '7'
  5.         JOIN `nalich` ON `goods`.`id` = `nalich`.`goodid` AND `nalich`.`amount`>0
  6.         JOIN `whouses` ON `whouses`.`id`= `nalich`.`whid`
  7. WHERE
  8.         `goods`.`tights`= 1
  9. GROUP BY goods.id


-----
PostgreSQL DBA
 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« SQL и Архитектура БД »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB