Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Web программирование > SQL, базы данных
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 27.09.2019, 14:22   #1
Armatus
Форумчанин
 
Регистрация: 09.05.2009
Сообщений: 122
По умолчанию Запрос с условием AND к таблице без уникального поля (primary key)

Всем доброго времени суток.
Впервые столкнулся с подобной задачей.

Имеем таблицу(products_attributes), описывающую взаимосвязь двух других таблиц (products и attributes)

product_id | attribute_id | text
147149 | 197 | Нет
147149 | 198 | Есть
246239 | 198 | Нет
356823 | 197 | Нет
435345 | 128 | Нет
324342 | 134 | Нет
323545 | 178 | Нет
455854 | 197 | Нет
....... и тд.

Нужно вывести product_id только тех значений, где встречаются записи attribute_id = 197 AND attribute_id = 198 одновременно, т.е.

SELECT product_id FROM product_attribute pa WHERE pa.attribute_id = '198' AND pa.attribute_id = '197' - не работает, оно и понятно почему

Если использовать OR - выведутся все записи: где есть attribute_id = 197, где есть attribute_id = 197 меня интересует только

SELECT product_id FROM product_attribute pa WHERE pa.attribute_id = '198' OR pa.attribute_id = '197' - не подходит, т.к. выводит все комбинации. Нужны product_id только тех где есть attribute_id = 197 AND attribute_id = 198 одновременно

Как правильно решить такую задачу?

Последний раз редактировалось Armatus; 27.09.2019 в 14:53.
Armatus вне форума Ответить с цитированием
Старый 27.09.2019, 14:58   #2
xxbesoxx
Участник клуба
 
Регистрация: 10.08.2010
Сообщений: 1,389
По умолчанию

Цитата:
Сообщение от Armatus Посмотреть сообщение
Как правильно решить такую задачу?
Запросе перечислить attribute_id = 197 и ещё attribute_id = 197 зачем ? когда можно pa.attribute_id IN (198,197)
Код:
drop table #product_attribute 
-----------
create table #product_attribute (product_id int ,
                                 attribute_id int 
                                )

--------------
insert into #product_attribute values (147149 , 197),
                                      (147149 , 198),
				        (246239 , 198),
					(356823 , 197 ),
					(435345 , 128),
					(324342 , 134),
					(323545 , 178),
					(455854 , 197)
--------------------------------------------
SELECT *
FROM #product_attribute pa WHERE pa.attribute_id IN (198,197)
Что у вас не работает ? и СУБД и тип поля какой ?
xxbesoxx вне форума Ответить с цитированием
Старый 27.09.2019, 14:59   #3
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,238
По умолчанию

ну так и свяжите их по product_id

например,
если всего два attribute_id требуется, тогда

Код:
SELECT pa.product_id FROM product_attribute pa 
WHERE  
pa.attribute_id = 197 
and pa.product_id in (select pb.product_id FROM product_attribute pa where  pa.attribute_id = 198)

Последний раз редактировалось Serge_Bliznykov; 27.09.2019 в 15:02.
Serge_Bliznykov вне форума Ответить с цитированием
Старый 27.09.2019, 15:15   #4
Armatus
Форумчанин
 
Регистрация: 09.05.2009
Сообщений: 122
По умолчанию

Цитата:
Сообщение от xxbesoxx Посмотреть сообщение
Запросе перечислить attribute_id = 197 и ещё attribute_id = 197 зачем ? когда можно pa.attribute_id IN (198,197)
Если я правильно понял IN - это аналог OR. Верно? Мне не подходит OR, т.к. мне требуется вывести product_id только тех позиций где attribute_id = 197, attribute_id = 198 присутствует одновременно.


Цитата:
Сообщение от Serge_Bliznykov Посмотреть сообщение
Код:
SELECT pa.product_id FROM product_attribute pa 
WHERE  
pa.attribute_id = 197 
and pa.product_id in (select pb.product_id FROM product_attribute pa where  pa.attribute_id = 198)
Этот пример вроде работает. Но что делать если attribute_id более 2-х? у меня такое возможно и нужно
Armatus вне форума Ответить с цитированием
Старый 27.09.2019, 15:20   #5
Armatus
Форумчанин
 
Регистрация: 09.05.2009
Сообщений: 122
По умолчанию

Нашел такое решение:

Код:
SELECT `product_id`,COUNT(*) count  FROM `oc_product_attribute` pa WHERE pa.attribute_id = '198' OR pa.attribute_id = '197' GROUP BY `product_id` HAVING COUNT(*) >= 2
Есть что-то более удачно для ситуаций, когда количество условий атрибутов может быть "любым"?
Armatus вне форума Ответить с цитированием
Старый 27.09.2019, 15:21   #6
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,238
По умолчанию

Цитата:
Сообщение от Armatus Посмотреть сообщение
Но что делать если attribute_id более 2-х? у меня такое возможно и нужно
написать столько соединений, сколько нужно attribute_id

Код:
SELECT pa.product_id FROM product_attribute pa 
WHERE  
pa.attribute_id = 197 
and pa.product_id in (select pb.product_id FROM product_attribute pa where  pa.attribute_id = 198)
and pa.product_id in (select pb.product_id FROM product_attribute pa where  pa.attribute_id = 199)
and pa.product_id in (select pb.product_id FROM product_attribute pa where  pa.attribute_id = 200)
and pa.product_id in (select pb.product_id FROM product_attribute pa where  pa.attribute_id = 201)
Serge_Bliznykov вне форума Ответить с цитированием
Старый 27.09.2019, 15:23   #7
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,238
По умолчанию

Цитата:
Сообщение от Armatus Посмотреть сообщение
Нашел такое решение:
это решение имеет большой недостаток:

если несколько раз повторяется одно и тоже значение, то запрос сработает

например, выберется 147149

Код:
147149 | 197 | Нет
147149 | 197 | Есть
246239 | 197 | Не
Serge_Bliznykov вне форума Ответить с цитированием
Старый 27.09.2019, 15:33   #8
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,695
По умолчанию

Цитата:
Сообщение от Serge_Bliznykov Посмотреть сообщение
это решение имеет большой недостаток
Что можно обойти вариантом
Код:
having count(distinct attribute_id) = 2
Если MySQL то можно заюзать ALL.
p51x вне форума Ответить с цитированием
Старый 27.09.2019, 15:38   #9
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 19,042
По умолчанию

Код:
SELECT V.product_id
  FROM (
    SELECT product_id,attribute_id
      FROM products_attributes
      WHERE attribute_id IN (195,214,777,888)
      GROUP BY product_id,attribute_id) V
  GROUP BY V.product_id
  HAVING COUNT(*) = 4
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 27.09.2019, 15:46   #10
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,238
По умолчанию

Цитата:
Сообщение от p51x Посмотреть сообщение
то можно обойти вариантом
Код:
having count(distinct attribute_id) = 2
не знал про такой вариант, спасибо.


Цитата:
Сообщение от Аватар Посмотреть сообщение
Код
Просто Супер!
у меня в голове эта мысль крутилась, но до реализации не дошла.
Serge_Bliznykov вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Выборка из базы без уникального поля. Paharok SQL, базы данных 11 27.09.2016 12:42
Сравнение всех значений поля в одной таблице со значением одного поля в другой ZulenkaSun Помощь студентам 3 07.06.2016 15:10
Автоматическое заполнение поля с определеным условием NinaGrnh Microsoft Office Access 0 05.03.2015 13:13
Сумма не уникального поля. Дмитрий mause Помощь студентам 4 25.01.2012 17:08
Вычисляемое поле в таблице ACCESS, создать вычисляемое поля в таблице аксес artlayers Microsoft Office Access 2 04.11.2009 19:29