#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'