Нужна помощь с SQL

Рейтинг: 1Ответов: 1Опубликовано: 26.10.2014

Есть таблица (wp_postmeta), структура такая:

id post_id   key            value
1    11    fromcity_1       Москва
2    11    fromdistrict_1   Садовое кольцо
3    11    fromcity_2       Воронеж
4    11    fromdistrict_1   Коминтерновский
5    13    fromcity_2       Воронеж
6    13    fromdistrict_1   Северный

И есть вот такой запрос:

 SELECT `post_id`
    FROM `wp_postmeta` AS p
    WHERE p.`key` LIKE 'fromcity_%' AND p.`value` = 'Москва'
        AND EXISTS (
            SELECT 1
            FROM wp_postmeta AS c
            WHERE c.post_id = p.post_id
                AND c.`key` = concat('fromdistrict_', substring(p.`key`, 9))
                AND c.`value` = 'Садовое кольцо'
        )

По идее, он должен возвращать post_id, где fromcity_1 = Вороклини, а fromdistrict_1 = Центр, но не работает.
При этом у ключей цифра 1 - ID, и у ключей fromcity_ и fromdistrict_ ID должен совпадать, что я и делаю вот здесь:

AND c.`key` = concat('fromdistrict_', substring(p.`key`, 9))

Но, видимо, я как-то неправильно использую substring, так как не работает...

Ответы

▲ 1

У вас паттерн EAV, в котором фильтры реализуются так:

select p.id 
from posts p
  left join postmeta pm1 on p.id = pm1.post_id and pm1.key = 'fromcity_1' 
  left join postmeta pm2 on p.id = pm2.post_id and pm2.key = 'fromdistrict_1'
  left join postmeta pm3 on p.id = pm3.post_id and pm3.key = 'fromcity_2' 
  left join postmeta pm4 on p.id = pm4.post_id and pm4.key = 'fromdistrict_2'
where
(pm1.value = 'Москва' and pm2.value = 'Садовое кольцо') 
or (pm3.value = 'Москва' and pm4.value = 'Садовое кольцо');

Такой запрос формируется в коде, в цикле по свойствам.
Это не совсем красиво и не очень быстро (должны быть правильные индексы, надеюсь, в wordpress они есть), но по крайней мере уложится в константное количество запросов. По поводу других вариантов, они, вероятно, тоже возможны, но не факт, что будут быстрее (или правильнее) как запрос, который вы сейчас используете.