Проблема с оператором MySQL Select OR? Сводит меня с ума

Я создаю плагин WP, который будет хранить настройки в настраиваемой таблице и извлекать их на основе идентификатора страницы или идентификатора категории, и если это находится в пределах временного интервала. Бит выбора даты работает нормально; проблема не исчезнет, ​​когда часть оператора, содержащая выбор даты, будет удалена.

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

$sql = "SELECT * FROM {$tablename}
WHERE (
      ( start_id = {$postid} OR ( start_id < {$postid} AND stop_id >= {$postid} ) AND scope = 'post' )
   OR ( start_id = {$categoryid} OR ( start_id < {$categoryid} AND stop_id >= {$categoryid} ) AND scope = 'category' )
 )
AND ( ...date selector... )";

Когда я использую этот код, он извлекает только запись категории, даже если есть запись сообщения, соответствующая критериям (которую она должна захватить первой). Если я удалю селектор категорий, он просто вытянет запись сообщения. Нет интерференции между start / stop_ID из разных строк; это уже проверил.

Базовая структура таблицы такова ... обратите внимание, что некоторые поля являются пустыми, потому что пользователь сможет указать либо диапазон, либо одну страницу или идентификатор категории.

ID    start_id    stop_id    scope       storedsettings
1     40          45         post        ...
2     50          NULL       category    ...
3     67          70         category    ...
4     71          NULL       post        ...

Большое спасибо за понимание этой проблемы!

ИЗМЕНИТЬ, чтобы ответить на некоторые комментарии: (1) @JESUS: вставка очень специфична и не допускает дублирования на основе идентификатора, поэтому всегда вытягивает одну строку; (2) @IVANIVAN: Что вы имеете в виду под приоритетом операторов? ИЛИ факторизуется перед И, поэтому я группирую И, а затем использую это как другую сторону ИЛИ. Или я неправильно понимаю твой ответ? Спасибо!

Ваш сценарий широко открыт для Атака с использованием SQL-инъекции Даже если вы избегаете ввода, это небезопасно! Используйте подготовленные параметризованные операторы в API MYSQLI_ или PDO

RiggsFolly 12.12.2018 01:08

@RiggsFolly Спасибо за внимание, но я правильно справляюсь с этим внутри Wordpress. Это очень урезанный код, поэтому вы можете понять мою проблему.

RalphTheWonderLlama 12.12.2018 01:11

@RalphTheWonderLlama Интересно. Ваш вопрос кажется правильным. Только для целей тестирования: что произойдет, если вы удалите часть (... селектор даты ...)?

EvE 12.12.2018 01:16

@EvE Никакой разницы. Это меня совершенно сбило с толку.

RalphTheWonderLlama 12.12.2018 01:25

У вас есть подвыражения формы (x OR (y1 AND y2) AND z) или (x OR y AND z). Вы уверены, что вам не нужно более четко указывать на порядок оценки? Думаю, это должен быть ((x OR y) AND z), он же ((x OR (y1 AND y2)) AND z)

Uueerdo 12.12.2018 01:26

Далее следует комментарий @Uueerdo - когда я делаю такой сложный выбор, я всегда заключаю в круглые скобки и использую их в достаточном количестве и в нужных местах, чтобы сделать все абсолютно конкретным.

ivanivan 12.12.2018 01:33

Какие критерии вы используете, когда он может вывести более 1 записи, но показывает только 1?

A Friend 12.12.2018 01:34

@ivanivan и [at] Jesus Я отредактировал вопрос, чтобы ответить на ваши комментарии. Спасибо!

RalphTheWonderLlama 12.12.2018 01:46

По внешнему виду параметризованные операторы @RiggsFolly здесь не работают - вы не можете параметризовать имя таблицы. Возможно, оператор OP может безопасно построить параметризованный оператор, используя только имя таблицы в качестве переменной, но им все равно нужны приличные проверки, чтобы предотвратить атаку SQLi.

e_i_pi 12.12.2018 01:51

Чтобы добавить к себе и @ivanivan, я всегда явно указываю порядок оценки с помощью скобок всякий раз, когда смешиваю И и ИЛИ, потому что: (1) честно говоря, мне не нужно помнить их приоритет, и (2) мне нужен «следующий парень» (чаще всего через год или около того), чтобы узнать порядок, который я намеревался.

Uueerdo 12.12.2018 01:55

@Uueerdo мудрые слова. окажет ли такой дополнительный факторинг в операторе select заметное влияние на скорость? Думаю, что нет, но стараюсь сделать это как можно более аккуратным.

RalphTheWonderLlama 12.12.2018 01:57

@RalphTheWonderLlama AND оценивается до OR. x OR (y1 AND y2) AND z === x OR (y1 AND y2 AND z), но вы, вероятно, захотите (x OR y1 AND y2) AND z

Nick 12.12.2018 03:03

@RalphTheWonderLlama OR обычно вредит больше, чем любые скобки, и производительность в таких ситуациях является второстепенной; поскольку без скобок это даже неправильное условие.

Uueerdo 12.12.2018 19:38
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
13
75
0

Другие вопросы по теме