¿Cuál es la forma correcta de escribir una consulta que contenga 'NOT IN' usando una declaración de condición?
Mi consulta es la siguiente:
SELECT DISTINCT nid FROM node WHERE language NOT IN
(SELECT language
FROM languages WHERE language = 'ab');
He intentado algo como lo siguiente:
$query->condition('n.' . $key, $value, 'not in (select language from
languages where language = $value)');
SELECT nid FROM node WHERE language != 'ab'
?Respuestas:
En el ejemplo específico, simplemente debe escribir la condición como:
En el caso genérico, donde necesita seleccionar las filas en una base de datos basándose en los valores devueltos por una subconsulta, debe considerar lo siguiente:
"NOT IN" se acepta como operador de
SelectQuery::condition()
. De hecho, se ejecutaría la siguiente consulta:Como se informa en las cláusulas condicionales ("Subselecciones"),
SelectQuery::condition()
acepta también un objeto que se implementaSelectQueryInterface
como valor para$value
, como el devuelto pordb_select()
; el problema es que en realidad puedes usarlo cuando el valor de$operator
es igual a"IN"
. Consulte las Subselecciones no funcionan en condiciones DBTNG, excepto cuando se usan como valor para IN .La única forma en que puedo ver el uso del operador "NO EN" con una subconsulta
condition
es:Ejecute la consulta principal estableciendo la condición como en el siguiente fragmento
$subquery_result
es la matriz que contiene el resultado de la subconsulta.De lo contrario, podría usar
where()
como otros dijeron, lo que acepta una cadena para la parte de la consulta que necesita agregar.Tenga en cuenta que
db_select()
es más lento esodb_query()
; debe usar el primero cuando sepa que la consulta podría ser alterada por otros módulos. De lo contrario, si se supone que otros módulos no deben usarsehook_query_alter()
para alterar su consulta, debe usarlosdb_query()
.En el caso de acceder a los nodos, si necesita obtener solo los nodos a los que tiene acceso un usuario, debe usar
db_select()
y agregar'node_access'
como etiqueta de la consulta, conSelectQuery::addTag()
. Por ejemplo,blog_page_last()
usa el siguiente código.Código similar es utilizado por
book_block_view()
.fuente
Al escribir consultas complejas definitivamente debe usar en
db_query()
lugar dedb_select()
.NOT IN
cláusula con una subconsulta con la API de base de datos de Drupal actual (es un problema conocido que se está resolviendo).db_select()
.db_query()
.Con respecto a su consulta, no estoy seguro de por qué desea utilizar una subconsulta (a menos que haya simplificado su ejemplo). Puedes escribirlo fácilmente así:
DISTINCT
no es necesario, ya quenid
es una clave principal, por lo que no se duplicará.fuente
También hay where () que permite agregar una condición where arbitraria a la consulta.
Ejemplo:
Como mencionó keithm, debe usar db_select () y addTag ('node_access') al seleccionar nodos que luego se muestran a los usuarios.
fuente
Una forma más fácil de usar db_select con una subselección NOT IN es simplemente usar el poco conocido
$ consulta-> donde
para agregar una arbitraria condición where.
p.ej:
fuente
Donde $ subquery_values es una matriz de $ key => $ nid formato como resultado de una subconsulta
funciona bien.
fuente