Подтвердить что ты не робот

Sql-запрос с несколькими операторами

У меня есть для меня довольно сложный запрос mysql, на котором я полностью застрял и не могу найти ответ для онлайн.

Здесь мой запрос:

SELECT
items.*
FROM
items
INNER JOIN
items_meta_data
WHERE
(
        (meta_key = 'lat' AND meta_value >= '55')
    OR
        (meta_key = 'lat' AND meta_value <= '65')
)
AND
(
        (meta_key = 'long' AND meta_value >= '20')
    OR
        (meta_key = 'long' AND meta_value <= '30')
)
GROUP BY
item_id

Конечно, я тестировал запрос только с 1-м выражением, и это работает нормально. Поэтому, если я передаю только длинную или лат-часть, я получаю результаты. Только когда я пытаюсь сшить их вместе, я получаю разные результаты.

Спасибо за помощь заранее!

Структура таблицы выглядит следующим образом:

Элементы таблицы: Я БЫ название предмета ITEM_DESCRIPTION

Таблица мета: meta_id item_id meta_key meta_value

Решение

Кому интересно, мне наконец удалось решить эту проблему. Спасибо всем за вашу помощь и внутренности.

SELECT
SQL_CALC_FOUND_ROWS items.* 
FROM
items
INNER JOIN
items_meta ON (items.ID = items_meta.post_id)
INNER JOIN
items_meta AS m1 ON (items.ID = m1.post_id)
WHERE
1=1
AND
items.post_type = 'post'
AND
(items.post_status = 'publish')
AND
( (items_meta.meta_key = 'lat' AND CAST(items_meta.meta_value AS SIGNED) BETWEEN '55'   AND '65')
AND
(m1.meta_key = 'long' AND CAST(m1.meta_value AS SIGNED) BETWEEN '20' AND '30') )
GROUP BY
items.ID
ORDER BY
items.date
DESC
4b9b3361

Ответ 1

Вы должны учитывать, что GROUP BY происходит после того, как условия предложения WHERE были оценены. А предложение WHERE всегда учитывает только одну строку, что означает, что в вашем запросе условия meta_key всегда будут препятствовать выбору любых записей, так как один столбец не может иметь несколько значений для одной строки.

А как насчет избыточных проверок meta_value? Если значение разрешено быть как меньшим, так и большим, чем заданное значение, то его фактическое значение вообще не имеет значения - проверка может быть опущена.

Согласно одному из ваших комментариев, вы хотите проверить места, расположенные на некотором расстоянии от определенного места. Чтобы получить правильные расстояния, вам действительно нужно использовать какую-то правильную функцию расстояния (см., Например, этот вопрос). Но этот SQL должен дать вам представление о том, как начать:

SELECT items.* FROM items i, meta_data m1, meta_data m2
    WHERE i.item_id = m1.item_id and i.item_id = m2.item_id
    AND m1.meta_key = 'lat' AND m1.meta_value >= 55 AND m1.meta_value <= 65
    AND m2.meta_key = 'lng' AND m2.meta_value >= 20 AND m2.meta_value <= 30

Ответ 2

Это..

(
        (meta_key = 'lat' AND meta_value >= '60.23457047672217')
    OR
        (meta_key = 'lat' AND meta_value <= '60.23457047672217')
)

совпадает с

(
        (meta_key = 'lat')
)

Объединяя все вместе (то же самое относится к фильтру long), у вас есть это невозможное предложение WHERE, которое не даст строк, потому что meta_key не может быть 2 значения в одной строке

WHERE
    (meta_key = 'lat' AND meta_key = 'long' )

Вам необходимо просмотреть своих операторов, чтобы убедиться, что вы правильно поняли

Ответ 3

Что такое meta_key? Разделите все условия meta_value, уменьшите, и в итоге получится следующее:

SELECT
*
FROM
meta_data
WHERE
(
        (meta_key = 'lat')
)
AND
(
        (meta_key = 'long')
)
GROUP BY
item_id

Так как meta_key никогда не может одновременно равняться двум различным значениям, результаты не возвращаются.


Основываясь на комментариях по всему этому вопросу и ответам до сих пор, похоже, что вы ищете что-то большее в соответствии с этим:

SELECT
*
FROM
meta_data
WHERE
(
    (meta_key = 'lat')
    AND
    (
        (meta_value >= '60.23457047672217')
        OR
        (meta_value <= '60.23457047672217')
    )
)
OR
(
    (meta_key = 'long')
    AND
    (
        (meta_value >= '24.879140853881836')
        OR
        (meta_value <= '24.879140853881836')
    )
)
GROUP BY
item_id

Обратите внимание на OR между условиями верхнего уровня. Это связано с тем, что вам нужны записи lat или long, поскольку ни одна запись никогда не будет lat и long.

Я все еще не уверен, что вы пытаетесь выполнить с помощью внутренних условий. Любое ненулевое значение будет соответствовать этим числам. Так что, может быть, вы сможете уточнить, что вы пытаетесь сделать там. Я также не уверен в цели предложения GROUP BY, но это может быть вне контекста этого вопроса.

Ответ 4

Можно ли увидеть структуру вашей таблицы? Если я это понимаю, то предположение, сделанное запросом, состоит в том, что запись может быть только meta_key - 'lat' или meta_key = 'long' не потому, что каждая строка имеет только один столбец meta_key и может содержать только одно соответствующее значение, а не 2. Это объясняет, почему вы не получаете результаты при подключении с помощью AND; это невозможно.