"ГДЕ НЕ В (ВЫБЕРИТЕ...)" с помощью SelectQuery?


Можно ли добавить предложение WHERE NOT IN (SELECT...) к объекту SelectQuery? Я смотрел на SelectQuery::условие(), и, похоже, этот синтаксис не учитывает:

public SelectQuery::condition($field, $value = NULL, $operator = NULL)

Кажется, что он допускает только выражения сравнения значений. Существует ли другой метод, обеспечивающий такой синтаксис?

Я рассматриваю условия порядка тысяч значений, поэтому кажется неэффективным иметь кучу условий AND value <> x.

 6
Author: tim.plunkett, 2011-08-04

4 answers

То, что вы ищете, это SelectQuery::существует(), к сожалению, похоже, что он не работает с "обычным способом" для создания такого предложения:
Обычно в предложении EXISTS вы помещаете СОЕДИНЕНИЕ в таблицы вне вашего подзапроса следующим образом:

SELECT n.nid
FROM node n
WHERE EXISTS (
  SELECT NULL
  FROM users u
  WHERE u.uid = n.uid
  AND u.status = 0)

Это возвращает узлы заблокированных пользователей (да, его можно легко построить без EXISTS, но это для учебных целей;).

Проблема здесь в том, что условие exists не поддерживает "внешнюю связь", часть u.uid = n.uid, поэтому вы должны создать полностью независимый запрос, который не очень эффективен IMHO.
В Drupal вы напишете следующее:

$query = db_select('node', 'n')
  ->fields('n', array('nid'));
$subquery = db_select('node', 'n2')
  ->fields('n2', array('nid'))
  ->join('users', 'u', 'n2.uid = u.uid'
  ->condition('u.status', 0);
$query->condition('', $subquery, 'EXISTS');
$result = $query->execute();

Вы также можете использовать db_query(), как вы делали в Drupal 6, и, конечно, доступен SelectQuery::notexists().

 8
Author: tostinni, 2011-08-04 21:29:21

Более простой способ использовать db_select с НЕ В подвыборке - это просто использовать

$ запрос->где

Для добавления произвольного условия where.

Например:

  // Count query for users without rid 3
  $query = db_select('users', 'u');
  $query->fields('u', array('uid'));
  $query->where('u.uid NOT IN(select uid from {users_roles} where rid = :rid)', array(':rid' => 3));  
  $result = $query->countQuery()->execute()->fetchField();
  drupal_set_message($result);
 2
Author: David Thomas, 2013-05-09 23:12:06

Фактически, вы можете использовать SelectQuery::условие() для создания подзапросов, например:

$query = db_select('users', 'u')
  ->fields('u', array('uid'))
  ->condition('u.uid', db_select('users_roles', 'r')->fields('r', array('uid')), 'NOT IN');

Если мы напечатаем этот запрос с помощью функции dpq() devel, он выведет:

SELECT u.uid AS uid
FROM 
{users} u
WHERE  (u.uid NOT IN  (SELECT r.uid AS uid
FROM 
{users_roles} r))

Надеюсь, это поможет;-)

 2
Author: Jelle, 2013-10-31 09:45:15

Я верю, что это поможет вам.

$query->where('n.nid NOT IN (:nids)', array(
    ':nids' => implode(',', $nids)
));
 0
Author: Vlad Stratulat, 2011-11-04 10:22:51