Как правильно написать запрос, содержащий NOT IN, используя оператор условия?
Мой запрос следующий:
SELECT DISTINCT nid FROM node WHERE language NOT IN
(SELECT language
FROM languages WHERE language = 'ab');
Я пробовал что-то вроде следующего:
$query->condition('n.' . $key, $value, 'not in (select language from
languages where language = $value)');
SELECT nid FROM node WHERE language != 'ab'
?Ответы:
В конкретном примере вы должны просто написать условие как:
В общем случае, когда вам нужно выбрать строки в базе данных на основе значений, возвращаемых из подзапроса, вы должны рассмотреть следующее:
«НЕ В» принимается как оператор из
SelectQuery::condition()
. Фактически будет выполнен следующий запрос:Как сообщается в условных предложениях («Subselects»),
SelectQuery::condition()
принимает также объект, реализующий вSelectQueryInterface
качестве значения$value
, например объект, возвращаемыйdb_select()
; проблема в том, что на самом деле вы можете просто использовать его, когда значение$operator
равно"IN"
. См. Подвыборы не работают в условиях DBTNG, за исключением случаев, когда они используются в качестве значения для IN .Единственный способ использования оператора NOT IN с подзапросом, который я вижу,
condition
- это:Выполните основной запрос, задав условие как в следующем фрагменте
$subquery_result
это массив, содержащий результат подзапроса.В противном случае вы можете использовать,
where()
как говорили другие, который принимает строку для части запроса, которую вы хотите добавить.Имейте в виду, что
db_select()
это медленнееdb_query()
; вы должны использовать первое, когда вы знаете, что запрос может быть изменен другими модулями. В противном случае, если другие модули не должны использоватьhook_query_alter()
для изменения вашего запроса, вы должны использоватьdb_query()
.В случае доступа к узлам, если вам нужно получить только те узлы, к которым у пользователя есть доступ, вам нужно использовать
db_select()
и добавить в'node_access'
качестве тега запроса, используяSelectQuery::addTag()
. Например,blog_page_last()
используется следующий код.Аналогичный код используется
book_block_view()
.источник
При написании сложных запросов вы должны определенно использовать
db_query()
вместоdb_select()
.NOT IN
предложение с подзапросом с текущим API базы данных Drupal (это известная проблема, которая решается).db_select()
.db_query()
.Что касается вашего запроса, я не уверен, почему вы хотите использовать подзапрос (если вы не упростили свой пример)? Вы можете написать это легко так:
DISTINCT
не является необходимым, посколькуnid
является первичным ключом, поэтому он не будет дублироваться.источник
Также есть where (), который позволяет добавить произвольное условие where в запрос.
Пример:
Как уже упоминалось, вы должны использовать db_select () и addTag ('node_access') при выборе узлов, которые затем отображаются для пользователей.
источник
Более простой способ использовать db_select с подвыбором NOT IN - просто использовать малоизвестный
$ Query-> где
добавить произвольное условие где.
например:
источник
Где $ subquery_values - это массив формата $ key => $ nid как результат подзапроса
это работает отлично.
источник