Помогите с запросом?

  • Автор темы Автор темы REMO
  • Дата начала Дата начала

REMO

Guest
Помогите с запросом?

Есть 4 талицы:

PHP:
1) tovari:
   tid | name | place_id | desc | prizn1 | prizn2
2) place:
   place_id | place_name
3) tovari_svoistva: (таблица связка)
   tid | propid
4) svoistva:
   propid | prop_name

Нужно выбрать все товары имеющие признаки 1 и 2 (prizn1 and prizn2) равными единице и соответственно данные из других таблиц касательно этого товара.

Мой запрос:
PHP:
SELECT * 
FROM tovari t1, place, tovari_svoistva t3, svoistva
WHERE t1.prizn1 = 1 AND t1.prizn2 = 1 AND place.place_id = t1.place_id AND t3.propid = t1.tid AND svoistva.propid = t3.propid
GROUP BY t3.propid
ORDER BY RAND(".$number.")"

Не хотит работать :( Т.е. выборка делается, но выбирается не то....
 
Автор оригинала: chira
что , не то ?
давай пример данных, что есть и чего должно быть ...
Я ступил... Нодо убрать GROUP BY t3.propid ....

Но тогда, если юзать ORDER BY RAND, то все строчки перемешаны.

Т.е. первая строчка запроса товар tid=1001, свойство = красный. Вторая строчка tid=1005, свойство = зеленый.
....
Двадцать пятая строчка tid=1001, свойство = мягкий.

А для вывода нужно чтобы было и ORDER BY RAND и в запросе товары шли tid=1001, свойство = красный. След строка tid=1001, свойство = мягкий. След строка tid=1005, свойство = зеленый.

А можно как то свойства в строчку уложить, а не делать так чтобы каждое свойство создавало дополнительную строку в результате запроса?
 
версия MySQL4?
Код:
(SELECT * 
FROM tovari t1, place, tovari_svoistva t3, svoistva 
WHERE t1.prizn1 = 1
 AND t1.prizn2 = 1
 AND place.place_id = t1.place_id
 AND t3.propid = t1.tid
 AND svoistva.propid = t3.propid 
GROUP BY t3.propid 
ORDER BY RAND(".$number.")"
) [b]ORDER BY tid, svoistva[/b]
в строку укладывай PHP
 
2chira

Не работает почему то такой запрос... :(
Как только убираю ORDER BY tid, svoistva все ок...

Может это быть из за того, что я поверх 3 версии mysql поставил 4-ую?

-~{}~ 11.06.04 15:01:

А разве может быть 2 ORDER BY?
 
Автор оригинала: Falc
REMO

Может, если ты скобки верно раставил
Спасибо, с этим разобрался... :D

Можно как то не перечислять все поля для выборки, а исключить какое то одно поле? К примеру поле desc, а все остальные выбрать.
 
-----

1) tovari:
tid | name | place_id | desc | prizn1 | prizn2
2) place:
place_id | place_name
3) tovari_svoistva: (таблица связка)
tid | propid
4) svoistva:
propid | prop_name
-----

Самый подходящий вариант- LEFT JOIN

SELECT * FROM tovari
LEFT JOIN tovari_svoistva USING (tid)
LEFT JOIN place USING (place_id)
LEFT JOIN svoistva ON (tovari_svoistva.propid=svoistva.propid)

.....
Получишь одну большую таблицу со всеми данными

И потом делай чего хочешь WHERE/ ORDER etc...
 
Автор оригинала: Kucovsky
Самый подходящий вариант- LEFT JOIN

SELECT * FROM tovari
LEFT JOIN tovari_svoistva USING (tid)
LEFT JOIN place USING (place_id)
LEFT JOIN svoistva ON (tovari_svoistva.propid=svoistva.propid)
Мне тяжело оценить по причине малого опыта. Но я так понимаю, что джоин все таки работает медленне, чем просто связка по таблицам. Стоит его использовать в моем случае?

И что он дает с точки зрения ORDER BY RAND по всему запросу и сортировки по какому то полю в подруппах запроса?
 
JOIN -одна из самых "приятных" функций .Ваш пример -просто классика для такого запроса.Практически JOIN просто "приклеивает" записи к первоначальным таблицам и если WHERE ограничивает только первую таблицу то скорость будет почти равна скорости селекта в первой таблице (конечно если проиндексрованы все поля по котором идет JOIN)

Еще одна "приятность" JOIN это то,что присоединяются поля NULL если нет данных в в присоединенных таблицах,чего не бывает при обычной связке.

В качестве "нагрузки" ,надо учитывать,что JOIN выдает несколько строк ,если есть несколько записей с тем же ключом в присоединяемых таблицах

Но в Вашем примере такое на первый взгляд не просматривается,Но это легко обходится с использованием GROUP или дополнительной обработкой на РНР .

Рассматривайте JOIN как просто дополнение данных к первой таблице и выполняйте по этой первой таблице все WHERE/ORDER/GROUP как в обычном запросе Это касается и ORDER BY RAND
 
Но я так понимаю, что джоин все таки работает медленне, чем просто связка по таблицам.
Цитата из MySQL manual:
MySQL поддерживает следующий синтаксис оператора JOIN при использовании в командах SELECT:

table_reference, table_reference
table_reference [CROSS] JOIN table_reference
table_reference INNER JOIN table_reference join_condition
table_reference STRAIGHT_JOIN table_reference
table_reference LEFT [OUTER] JOIN table_reference join_condition
table_reference LEFT [OUTER] JOIN table_reference
table_reference NATURAL [LEFT [OUTER]] JOIN table_reference
{ OJ table_reference LEFT OUTER JOIN table_reference ON conditional_expr }
table_reference RIGHT [OUTER] JOIN table_reference join_condition
table_reference RIGHT [OUTER] JOIN table_reference
table_reference NATURAL [RIGHT [OUTER]] JOIN table_reference

где table_reference определено, как:

table_name [[AS] alias] [[USE INDEX (key_list)] | [IGNORE INDEX (key_list)] | [FORCE INDEX (key_list)]]

и join_condition определено, как:

ON conditional_expr |
USING (column_list)
Так что JOIN (...FROM table1 LEFT JOIN table2 ON table1.id1 = table2.id2) -- один из видов связывания, равноценный перемножению таблиц (...FROM table1, table2 WHERE table1.id1 = table2.id2), причем в большинстве случаев более эффективный, чем такое перемножение.
Стоит его использовать в моем случае?
Да.
 
2lucas

Джоин работает быстрее, только что измерил экспериментальным путем. На истинность не претендую, т.к. мог не учесть каких то аспектов.

Но вот объяснение почему он работает быстрее, я не вижу в мане :(

-~{}~ 12.06.04 13:10:

Ну это уже мелочи....

Мне лучше с этим кто-нибудь помог бы http://phpclub.ru/talk/showthread.php?s=&threadid=51445&rand=0
 
Что-то я ничего не понял, у человека было простое связывание, ему предложили заменить LEFT JOIN, который работает медленее, в итоге стало работать быстрее. Сомнительно как-то.

Кстати, вместо RAND(".$number.") лучше писать RAND().
 
Автор оригинала: Falc
Что-то я ничего не понял, у человека было простое связывание, ему предложили заменить LEFT JOIN, который работает медленее, в итоге стало работать быстрее. Сомнительно как-то.

Кстати, вместо RAND(".$number.") лучше писать RAND().
RAND() не получится, тк мне надо, чтобы случайная последовательность была как бы и не случайной. Т.е. чтобы я мог вызвать эту случайную последовательность при каком то числе.

Быстрее джоин или медленее. По тестам вроде быстрее. А здесь, кто говорит, что быстрее, кто говрит, что медленнее. Нет единства в рядах программистов. :D
 
Сверху