Qual é a maneira correta de escrever uma consulta contendo 'NOT IN' usando uma instrução de condição?
Minha consulta é a seguinte:
SELECT DISTINCT nid FROM node WHERE language NOT IN
(SELECT language
FROM languages WHERE language = 'ab');
Eu tentei algo como o seguinte:
$query->condition('n.' . $key, $value, 'not in (select language from
languages where language = $value)');
SELECT nid FROM node WHERE language != 'ab'
?Respostas:
No exemplo específico, você deve simplesmente escrever a condição como:
No caso genérico, em que você precisa selecionar as linhas em um banco de dados com base nos valores retornados de uma subconsulta, considere o seguinte:
"NOT IN" é aceito como operador de
SelectQuery::condition()
. De fato, a seguinte consulta seria executada:Conforme relatado nas cláusulas condicionais ("Subseleciona"),
SelectQuery::condition()
também aceita um objeto implementadoSelectQueryInterface
como valor para$value
, como o retornado pordb_select()
; o problema é que, na verdade, você pode usá-lo apenas quando o valor de$operator
for igual a"IN"
. Consulte Subselecionamentos não funcionam em condições DBTNG, exceto quando usado como valor para IN .A única maneira de ver o uso do operador "NOT IN" com uma subconsulta
condition
é:Execute a consulta principal definindo a condição como no seguinte trecho
$subquery_result
é a matriz que contém o resultado da subconsulta.Caso contrário, você pode usar
where()
como outros disseram, que aceita uma string para a parte da consulta que você precisa adicionar.Tenha em mente que
db_select()
é mais lento issodb_query()
; você deve usar o primeiro quando souber que a consulta pode ser alterada por outros módulos. Caso contrário, se outros módulos não devem ser usadoshook_query_alter()
para alterar sua consulta, você deve usá-lodb_query()
.No caso de acessar nós, se você precisar obter apenas os nós aos quais um usuário tem acesso, precisará usar
db_select()
e adicionar'node_access'
como tag da consulta, comSelectQuery::addTag()
. Por exemplo,blog_page_last()
usa o seguinte código.Código semelhante é usado por
book_block_view()
.fonte
Ao escrever consultas complexas, você definitivamente deve usar em
db_query()
vez dedb_select()
.NOT IN
cláusula com uma subconsulta com a API atual do banco de dados Drupal (é um problema conhecido que está sendo resolvido).db_select()
.db_query()
.Em relação à sua consulta, não sei por que você deseja usar uma subconsulta (a menos que tenha simplificado seu exemplo)? Você pode escrever facilmente assim:
DISTINCT
não é necessário, poisnid
é uma chave primária, para que não seja duplicada.fonte
Também há where () que permite adicionar uma condição where arbitrária à consulta.
Exemplo:
Como o keithm mencionado, você deve usar db_select () e addTag ('node_access') ao selecionar nós que serão exibidos aos usuários.
fonte
Uma maneira mais fácil de usar o db_select com uma sub-seleção NOT IN é usar o pouco conhecido
$ query-> where
para adicionar uma condição where arbitrária.
por exemplo:
fonte
Onde $ subquery_values é uma matriz do formato $ key => $ nid como resultado de uma subconsulta
Funciona bem.
fonte