it-swarm-id.com

"DIMANA TIDAK DI (PILIH ...)" dengan SelectQuery?

Apakah mungkin untuk menambahkan objek WHERE NOT IN (SELECT...) clause ke objek SelectQuery? Saya melihat SelectQuery :: condition () , dan sepertinya tidak mengizinkan sintaks ini:

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

Tampaknya hanya memungkinkan untuk ekspresi perbandingan nilai. Apakah ada metode lain yang menyediakan sintaks ini?

Saya melihat kondisi pada urutan ribuan nilai, jadi sepertinya tidak efisien untuk memiliki banyak AND value <> x kondisi.

6
user1359

Apa yang Anda cari adalah SelectQuery :: exist () , sayangnya sepertinya tidak berfungsi dengan "cara umum" untuk membangun klausa seperti itu:
Biasanya dalam klausa EXISTS Anda menempatkan GABUNG pada tabel di luar sub kueri Anda seperti ini:

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

Ini mengembalikan node dari pengguna yang diblokir (ya itu dapat dibangun dengan mudah tanpa EXISTS tetapi itu untuk tujuan pengajaran;).

Masalahnya di sini adalah kondisi exists tidak mendukung "tautan luar", u.uid = n.uid bagian sehingga Anda harus membangun kueri yang sepenuhnya independen yang tidak terlalu efisien IMHO.
Dalam Drupal Anda akan menulis ini:

$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();

Anda juga dapat menggunakan db_query () seperti yang Anda lakukan di Drupal 6 dan tentu saja SelectQuery :: notExists () tersedia.

8
tostinni

Cara yang lebih mudah untuk menggunakan db_select dengan subselect NOT IN adalah dengan menggunakannya

$ query-> where

untuk menambahkan kondisi tempat sewenang-wenang.

misalnya:

  // 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
David Thomas

Acutally, Anda dapat menggunakan SelectQuery :: condition () untuk membuat subselect seperti:

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

Jika kita mencetak kueri ini menggunakan fungsi dpq () dari devel, ia akan menampilkan:

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

Saya harap ini membantu ;-)

2
Jelle

Saya percaya ini akan membantu Anda.

$query->where('n.nid NOT IN (:nids)', array(
    ':nids' => implode(',', $nids)
));
0
Vlad Stratulat