Как сформировать SQL запрос по двум ключам?

341
11 июля 2017, 20:19

Есть такая таблица

----------------------------
product | key    | values
----------------------------
60      | key_1  | "строка"
----------------------------
60      | key_2  | 25
----------------------------

Как сформировать запрос таким образом, что бы достать запись c проверкой по двум ключам

key = 'key_1' AND values = 'строка' AND key = 'key_2' AND value >= 25

То есть у нас должна выбраться запись которая имеет ключ key_1 который равен строка и в тоже время имеет ключ key_2 который равен (или меньше) 25

Проще говоря это опции товара, и по ним надо делать фильтрацию. В данном примере у товара есть две опции и в данной таблице записаны значения этих опций, одна строковая другая число. Так вот надо что бы товар можно было вытащить если одно значение у него "строка" а другое значение больше или ровно 25

Сделал вот так

SELECT * FROM `params` WHERE (params.key, params.value) IN( ('obrabotka','Топленое'), ('zhirnost', 25) )

Но вот эти части никак между собой не связаны

('obrabotka','Топленое'), ('zhirnost', 25)

В идеале было бы вот так

('obrabotka','Топленое') AND ('zhirnost', 25)

Пример:

Запрос

SELECT * FROM `params` WHERE params.key = 'obrabotka' AND params.value = 'Топленое'

Ответ

Запрос

SELECT * FROM `params` WHERE params.key = 'zhirnost' AND params.value >= 25

Ответ

Как объединить эти два запроса что бы получилось что то такое ?

WHERE params.key = 'obrabotka' AND params.value = 'Топленое' AND params.key = 'zhirnost' AND params.value >= 25
Answer 1

В иных СУБД это могло бы выглядеть так:

SELECT product
FROM params
WHERE params.key = 'obrabotka' AND params.value = 'Топленое' 
INTERSECT
SELECT product
FROM params
WHERE params.key = 'zhirnost' AND params.value >= 25 --только тут явно нужно value преобразовать в число

В MySQL медленный вариант будет выглядеть так:

SELECT *
FROM(
  SELECT product,
    MAX(IF(params.key = 'obrabotka', value, NULL))obrabotka,
    MAX(IF(params.key = 'zhirnost', value, NULL))zhirnost
  FROM params
  GROUP BY product
)T
WHERE obrabotka='Топленое' AND zhirnost >= 25 --только тут явно нужно value преобразовать в число

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

SELECT *
FROM(
  SELECT product
  FROM params
  WHERE params.key = 'obrabotka' AND params.value = 'Топленое' 
  UNION ALL
  SELECT product
  FROM params
  WHERE params.key = 'zhirnost' AND params.value >= 25 --только тут явно нужно value преобразовать в число 
)T
GROUP BY product HAVING COUNT(*)=2

UPD: или даже так:

SELECT p1.product, p1.value obrabotka, p2.value zhirnost
FROM params p1
  JOIN params p2 ON p1.product = p2.product
WHERE p1.key = 'obrabotka' AND p1.value = 'Топленое' 
  AND p2.key = 'zhirnost' AND p2.value >= 25
READ ALSO
Если есть UPDATE, иначе INSERT

Если есть UPDATE, иначе INSERT

Есть таблица без первичного ключа:

223
PHPMyadmin проблема с импортом CSV файла

PHPMyadmin проблема с импортом CSV файла

Проблема вот в чем, когда импортирую файл с английскими названиями, все проходит успешно, но как только стоит сменить любое поля на русские...

267
Медленные запросы autoload = 'yes'

Медленные запросы autoload = 'yes'

Сайт на WordPressУ меня много медленных запросов в БД:

230
mysql запросы с множественным условием if

mysql запросы с множественным условием if

Добрый деньЕсть код который получает из базы список районов:

272