"ГДЕ НЕ В (ВЫБЕРИТЕ...)" с помощью SelectQuery?
Можно ли добавить предложение WHERE NOT IN (SELECT...)
к объекту SelectQuery
? Я смотрел на SelectQuery::условие(), и, похоже, этот синтаксис не учитывает:
public SelectQuery::condition($field, $value = NULL, $operator = NULL)
Кажется, что он допускает только выражения сравнения значений. Существует ли другой метод, обеспечивающий такой синтаксис?
Я рассматриваю условия порядка тысяч значений, поэтому кажется неэффективным иметь кучу условий AND value <> x
.
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().
Более простой способ использовать 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);
Фактически, вы можете использовать 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))
Надеюсь, это поможет;-)
Я верю, что это поможет вам.
$query->where('n.nid NOT IN (:nids)', array(
':nids' => implode(',', $nids)
));