Помогите с PHP Select Query: ГДЕ x = y И a = b И возможно ли (c!= d)?

#php #mysql #select #phpquery

#php #mysql #выберите #phpquery

Вопрос:

Хорошо, поехали… У меня есть select query, обращающийся к очень абстрактной базе данных. Мой текущий запрос просматривает 5 таблиц (используя для этого 6 «И»)… не весело) и возвращает любые записи, соответствующие всем критериям, как и должно быть.

Мой вопрос заключается в следующем: могу ли я добавить что-то к моему текущему запросу, который в основном гласит «Если запись соответствует всем этим, но не соответствует всем этим«.

Пример:

Мой текущий запрос:

 $query = "SELECT s.state_name FROM `tbl_records` r, `tbl_states` s,
 `tbl_events` e, `tbl_fields` f, `tbl_field_values` v 
WHERE s.state_id = r.state_id AND f.field_id = '$field_id' AND 
v.field_id = f.field_id AND v.event_id = e.event_id AND e.record_id = r.record_id
 AND v.value_id = '$field_value' AND v.is_latest = '1'";
  

Уродливый и длинный, не так ли? Что ж, это дает мне все записи, которые соответствуют одному критерию (запись соответствует $ field_id и $ field_value).

Теперь мне нужно взять все записи, которые находит этот запрос, но вычесть любую запись, которая соответствует другим критериям, что-то вроде » AND (v.event_id = e.event_id AND f.field_id = '155' AND v.value_id != '1');

Это длинная и уродливая версия. Подводя итог:

Мне нужно создать запрос, который выглядит примерно так:
Select "s.state_name FROM a,b,c,d WHERE (a.1 = b.2 AND c.3 = d.4 *etc*) AND ONLY IF (a.2 = b.3 AND c.4 != d.5)"

Возможно ли это? Можете ли вы создать запрос, который говорит «Если соответствует всему этому И не соответствует всему этому»?

Дайте мне знать, если кому-нибудь понадобятся дополнительные разъяснения… Что меня бы не удивило. Спасибо вам всем.

ОБНОВЛЕНИЕ:: Добавляю изображение, чтобы попытаться уточнить, что мне нужно.

структура таблицы http://www.everythingsirie.com/values.jpg

Два значения в разделе «необходимо добавить» должны относиться к одной и той же записи. Итак, в plan english «Для этой же записи в таблице ‘tbl_field_values’, если запись имеет ‘field_id’, равный ‘155’, И значение field_value, равное ‘1’, не включайте ее».

Но обратите внимание, что теперь есть два идентификатора поля и value_id. Это то, что ставит меня в тупик…

ОБНОВЛЕНИЕ 2::

Я обновил запрос, используя ответы от @M42 и @Michael. Однако я все еще получаю одинаковое количество возвратов с или без «И НЕ»…

 $query = "SELECT s.state_name FROM `tbl_records` r
INNER JOIN `tbl_states` s ON s.state_id = r.state_id
INNER JOIN `tbl_events` e ON e.record_id = r.record_id
INNER JOIN `tbl_field_values` v ON v.event_id = e.event_id
INNER JOIN `tbl_fields` f ON v.field_id = f.field_id
WHERE f.field_id = '$field_id'
AND v.value_id = '$field_value'
AND v.is_latest = '1'
AND NOT (v.field_id = '155' AND v.value_id = '1')";
  

Я думаю, проблема в том, что field_id и value_id, которые мне нужно НЕ сопоставлять, находятся в той же таблице, что и field_id и value_id, которые мне действительно нужно сопоставить. Вот рисунок, показывающий идентификатор поля, равный 155, с идентификатором значения, равным 1 и 0.

Мне нужно НЕ включать записи, которые имеют value_id равный 1, ТОЛЬКО когда field_id равен 155… Но в то же время я пытаюсь выбрать записи с field_id=12 и value_id = 1…

структура таблицы http://www.everythingsirie.com/valueid.jpg

Я знаю, что это беспорядок… Извините.

Комментарии:

1. Чем это отличается от простого добавления большего количества AND операторов в ваше WHERE предложение?

2. ЗАПУСТИТЕ АДМИНИСТРАТОРА БАЗЫ данных. Вот с чего я бы начал.

3.Первый запрос ищет любые записи, которые соответствуют одному field_id, но мне нужно вычесть записи, которые соответствуют другому field_id , а также не соответствуют другому полю

4. @Калеб, я согласен с @Matthew в этом вопросе. Я не вижу никакой разницы в вашем запросе и добавлении большего AND к инструкции. Вместо того, чтобы задавать вопрос напрямую, возможно, вам следует предоставить образец структуры данных и вопрос, на который могут ответить данные, например «как я могу получить все события в этом состоянии?»

5. Достаточно справедливо. Позвольте мне посмотреть, что я могу собрать вместе

Ответ №1:

Насколько понимаю, вы можете добавить в свой запрос :

 AND NOT (f.field_id = '155' AND v.value_id != '1')
  

Комментарии:

1. По какой-то причине это все еще дает мне то же количество возвратов. С этим добавлением или без него я все еще получаю все возвращенные записи. Это выглядит как правильная вещь, но я, возможно, неправильно использую ее в этой ситуации…

2. ОК. Итак, я нашел способ сделать это, объединив ответы как от @Michael, так и от @M42. В итоге я получил его, используя AND NOT EXISTS полный SELECT запрос внутри него, вот так: AND NOT EXISTS     (     SELECT *     FROM tbl_field_values v     INNER JOIN tbl_events e ON v.event_id = e.event_id     WHERE e.record_id = r.record_id     AND v.is_latest = 1     AND (v.field_id = 155 AND v.value_id = 1)     )"; Это было для меня непосильным делом, и я не смог бы сделать это без чьей-либо помощи. Спасибо.

Ответ №2:

Вместо этого вы можете использовать ВНУТРЕННИЕ объединения для объединения таблиц. Они выполняют то же самое, что и объединение таблиц с помощью предложений WHERE, но выглядят приятнее IMHO…it не загромождает ваше предложение WHERE.

 SELECT s.state_name FROM `tbl_records` r
INNER JOIN `tbl_states` s ON s.state_id = r.state_id
INNER JOIN `tbl_events` e ON e.record_id = r.record_id
INNER JOIN `tbl_field_values` v ON v.event_id = e.event_id
INNER JOIN `tbl_fields` f ON v.field_id = f.field_id
WHERE f.field_id = '$field_id'
AND v.value_id = '$field_value'
AND v.is_latest = '1'
  

Комментарии:

1. Это очень полезно для поддержания чистоты и большей управляемости. Спасибо!

Ответ №3:

Здесь для обновления 2:

 SELECT s.state_name
FROM `tbl_records` r
  INNER JOIN `tbl_states` s ON s.state_id = r.state_id
  INNER JOIN `tbl_events` e ON e.record_id = r.record_id
  INNER JOIN `tbl_field_values` v ON v.event_id = e.event_id
  INNER JOIN `tbl_fields` f ON v.field_id = f.field_id
WHERE ((f.field_id = '12' AND v.value_id = '1')
  OR (v.field_id = '155' AND v.value_id != '1'))
  AND v.is_latest = '1'