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

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.")"
Не хотит работать :( Т.е. выборка делается, но выбирается не то....
 

REMO

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

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

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

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

А можно как то свойства в строчку уложить, а не делать так чтобы каждое свойство создавало дополнительную строку в результате запроса?
 

chira

Новичок
версия 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
 

REMO

Guest
2chira

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

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

-~{}~ 11.06.04 15:01:

А разве может быть 2 ORDER BY?
 

REMO

Guest
Автор оригинала: Falc
REMO

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

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

Kucovsky

Новичок
-----

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...
 

REMO

Guest
Автор оригинала: 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 по всему запросу и сортировки по какому то полю в подруппах запроса?
 

Kucovsky

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

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

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

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

Рассматривайте JOIN как просто дополнение данных к первой таблице и выполняйте по этой первой таблице все WHERE/ORDER/GROUP как в обычном запросе Это касается и ORDER BY RAND
 

lucas

Guest
Но я так понимаю, что джоин все таки работает медленне, чем просто связка по таблицам.
Цитата из 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), причем в большинстве случаев более эффективный, чем такое перемножение.
Стоит его использовать в моем случае?
Да.
 

REMO

Guest
2lucas

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

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

-~{}~ 12.06.04 13:10:

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

Мне лучше с этим кто-нибудь помог бы http://phpclub.ru/talk/showthread.php?s=&threadid=51445&rand=0
 

Falc

Новичок
Что-то я ничего не понял, у человека было простое связывание, ему предложили заменить LEFT JOIN, который работает медленее, в итоге стало работать быстрее. Сомнительно как-то.

Кстати, вместо RAND(".$number.") лучше писать RAND().
 

REMO

Guest
Автор оригинала: Falc
Что-то я ничего не понял, у человека было простое связывание, ему предложили заменить LEFT JOIN, который работает медленее, в итоге стало работать быстрее. Сомнительно как-то.

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

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