powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Прошу помочь сделать выборку
24 сообщений из 24, страница 1 из 1
Прошу помочь сделать выборку
    #39514956
atillus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Приветствую всех!
Есть две связанные таблицы: products и properties
В таблице products поля:
id | prod_title | prod_price

В таблице properties поля:
prod_id | property_name | property_value

Связь: properties.prod_id => products.id

Для одного товара в таблице products может быть много позиций в таблице properties.
Например:

Есть товар в products (id = 1):

1 | Туфли | 3000

И его свойства в таблице properties:

1 | Размер | 37
1 | Пол | Женский
1 | Цвет | Белый
1 | Каблук | Высокий
... и т.д.

Мне нужно получить товары по нескольким значениям свойств... Например выбрать все товары, у которых цвет белый и пол женский...

Пытаюсь сделать так:

Код: sql
1.
2.
3.
4.
5.
6.
SELECT `id`, `prod_title`, `prod_price` FROM `products`
LEFT OUTER JOIN `properties`
ON `products`.`id` = `properties`.`prod_id`
WHERE `properties`.`property_name` = 'Цвет' AND `properties`.`property_value` = 'Белый'
AND `properties`.`property_name` = 'Пол' AND `properties`.`property_value` = 'Женский'
LIMIT 20;



Если убрать последнее условие 'AND' - то работает. Но не получается сделать выборку сразу по двум свойствам...
Прошу помочь.
...
Рейтинг: 0 / 0
Прошу помочь сделать выборку
    #39514965
atillus,

почитать про OR, [NOT] EXISTS, GROUP BY + HAVING
...
Рейтинг: 0 / 0
Прошу помочь сделать выборку
    #39514966
Darkripple
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
почитайте про IN (SELECT ...) или EXISTS (SELECT ...)
...
Рейтинг: 0 / 0
Прошу помочь сделать выборку
    #39514968
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
atillus,

Код: sql
1.
2.
3.
4.
select * from product d
where exists (select * from properties p where p.prod_id = d.prod_id and p.property_name = 'Цвет' and p.property_value = 'Белый' )
and exists (select * from properties p where p.prod_id = d.prod_id and p.property_name = 'Вкус' and p.property_value = 'Горький' )
...
...
Рейтинг: 0 / 0
Прошу помочь сделать выборку
    #39514969
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый Э - Эхatillus,

почитать про OR, [NOT] EXISTS, GROUP BY + HAVING

group by то нафига ?
...
Рейтинг: 0 / 0
Прошу помочь сделать выборку
    #39514972
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
2.
3.
4.
5.
6.
7.
SELECT p.*
FROM products p, properties pp
WHERE p.id = pp.prod_id
AND (pp.property_name,pp.property_value) IN (('Цвет','Белый'),
                                             ('Пол','Женский'))
GROUP BY p.id 
HAVING COUNT(*) = 2
...
Рейтинг: 0 / 0
Прошу помочь сделать выборку
    #39514980
atillus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: sql
1.
AND (pp.property_name,pp.property_value) IN (('Цвет','Белый'), ('Пол','Женский'))



Как просто! :)
...
Рейтинг: 0 / 0
Прошу помочь сделать выборку
    #39514985
atillus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Но такой вариант работает неверно, ибо если написать

Код: sql
1.
IN (('Цвет','Белый'), ('Пол','Средний'))



отдаст все белого цвета :)
...
Рейтинг: 0 / 0
Прошу помочь сделать выборку
    #39514990
atillus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
подзапрос AND EXISTS - правильно работает.

Спасибо за помощь!
...
Рейтинг: 0 / 0
Прошу помочь сделать выборку
    #39514992
paver
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
atillus,
Избавиться от LEFT
Использовать OR
Группировать по id
Оставить те id, где count по id строго равен числу отбираемых параметров
...
Рейтинг: 0 / 0
Прошу помочь сделать выборку
    #39514994
paver
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
блин, долго писал, уже ответили
...
Рейтинг: 0 / 0
Прошу помочь сделать выборку
    #39515076
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
atillusтакой вариант работает неверно, ибо если написать
Код: sql
1.
IN (('Цвет','Белый'), ('Пол','Средний'))


отдаст все белого цветаЭто ты ляпнул, чтобы хоть что-то сказать? лучше попробовал бы...
...
Рейтинг: 0 / 0
Прошу помочь сделать выборку
    #39515426
paver
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina,
а почему условие связывания не в ON, а в WHERE?
Так лучше или пофиг?
...
Рейтинг: 0 / 0
Прошу помочь сделать выборку
    #39515449
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
paverпочему условие связывания не в ON, а в WHERE?
Абсолютно пофиг. Разница - чисто синтаксическая. Запрос один, тексты просто разные.
Равно как и между терминами "условия связывания" и "условия отбора" в случае внутреннего связывания разница чисто в наборе использованных букв (а у автора связывание именно такое, внутреннее, просто он не знает о существовании INNER JOIN и везде лепит LEFT).
...
Рейтинг: 0 / 0
Прошу помочь сделать выборку
    #39515486
paver
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina,
понял, спасибо. Просто думаю, что коль скоро в информационной модели между сущностиями есть (подразумевается) связь (один-ко-многим), то желательно ее и в запросе отобразить. Ну, методически правильнее, что ли.
...
Рейтинг: 0 / 0
Прошу помочь сделать выборку
    #39515494
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
paverколь скоро в информационной модели между сущностиями есть (подразумевается) связь (один-ко-многим), то желательно ее и в запросе отобразить.
Она и отображается, собсно... связь - не более чем некое выражение, которое истинно для связанных записей. и ложно для несвязанных. Всё. Местоположение этого выражения сущностью связи не определяется.
...
Рейтинг: 0 / 0
Прошу помочь сделать выборку
    #39515660
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Akina
Код: sql
1.
2.
3.
4.
5.
6.
7.
SELECT p.*
FROM products p, properties pp
WHERE p.id = pp.prod_id
AND (pp.property_name,pp.property_value) IN (('Цвет','Белый'),
                                             ('Пол','Женский'))
GROUP BY p.id 
HAVING COUNT(*) = 2



Я давно знаю о этом твоём подходе, и он мне не нравится. Без причин, просто не нравится.
Но я всё время пытался найти контрпример, когда эта твоя фигня не будет работать.

И ВОТ ЭВРИКА!

Если в таблице свойств случайно продублируются записи
('Цвет','Белый'),
или
('Пол','Женский')
(будет более одной), то твой запрос не вернёт данные.

Но ты выкрутишься, напишешь

Код: sql
1.
HAVING COUNT(*) >= 2



...

как же тебя прижучить ?
...
Рейтинг: 0 / 0
Прошу помочь сделать выборку
    #39515783
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivон мне не нравится. Без причин, просто не нравится.Верю. Но у него есть хорошее свойство - универсальность.

[quote MasterZiv]Если в таблице свойств случайно продублируются записи[SRC sql]... то первым делом я спрошу "Какой [censored] забыл создать уникальный индекс?". А потом просто посчитаю COUNT(DISTINCT CONCAT(pp.property_name,CHAR(0),pp.property_value))
...
Рейтинг: 0 / 0
Прошу помочь сделать выборку
    #39515983
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Akina,
но твоей запрос ещё и хуже по производительности.
мой может на раннем этапе уже отсечь много записей по первому фильтру, затем применять остальные.

Твой будет жестоко агрегировать все записи в таблице...

если твой примерять, надо Хотя Бы вынести один из фильтров в WHERE...
...
Рейтинг: 0 / 0
Прошу помочь сделать выборку
    #39515985
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivAkina,
но твоей запрос ещё и хуже по производительности.
мой может на раннем этапе уже отсечь много записей по первому фильтру, затем применять остальные.

Твой будет жестоко агрегировать все записи в таблице...

если твой примерять, надо Хотя Бы вынести один из фильтров в WHERE...

не, я неправ, твой тоже может оптимизироваться...

но все равно не нравится он мне!
...
Рейтинг: 0 / 0
Прошу помочь сделать выборку
    #39516139
paver
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MasterZiv,
Зато красиво. И без exists (select...) (который, к стыду еще плохо понимаю).
А что если вторую таблицу жойнить дважды, а потом запускать отбор? Distinct, кстати, решает проблему дублей характеристик. Как у такого запроса с производительностью?
...
Рейтинг: 0 / 0
Прошу помочь сделать выборку
    #39516146
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
paverА что если вторую таблицу жойнить дважды
При фиксированном количестве фильтров это обычная практика:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
SELECT p.* 
FROM products p
JOIN properties pp1 ON p.id=pp1.prod_id
                   AND pp1.property_name = 'Цвет' 
                   AND pp1.property_value = 'Белый'
JOIN properties pp2 ON p.id=pp2.prod_id
                   AND pp2.property_name = 'Пол' 
                   AND pp2.property_value = 'Женский'


При нефиксированном - можно использовать динамическую "подгрузку" пакета условий на стороне клиента или в хранимой процедуре.
...
Рейтинг: 0 / 0
Прошу помочь сделать выборку
    #39516312
paver
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
AkinaПри нефиксированном ...
Ага, не подумал. Точнее, уже забыл, что в условии - "по нескольким значениям свойств"
...
Рейтинг: 0 / 0
Прошу помочь сделать выборку
    #39516404
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
paverMasterZiv,
Зато красиво. И без exists (select...) (который, к стыду еще плохо понимаю).
А что если вторую таблицу жойнить дважды, а потом запускать отбор? Distinct, кстати, решает проблему дублей характеристик. Как у такого запроса с производительностью?

Да там примерно одинаково хреново с производительностью...
...
Рейтинг: 0 / 0
24 сообщений из 24, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Прошу помочь сделать выборку
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]