मैं क्वेरी में "NOT IN" का उपयोग कैसे करूं?


26

एक शर्त बयान का उपयोग करके 'NOT IN' युक्त क्वेरी लिखने का उचित तरीका क्या है?

मेरी क्वेरी निम्नलिखित है:

SELECT DISTINCT nid FROM node WHERE language NOT IN 
  (SELECT language 
    FROM languages WHERE language = 'ab');

मैंने निम्नलिखित की तरह कुछ करने की कोशिश की है:

$query->condition('n.' . $key, $value, 'not in (select language from 
  languages where language = $value)');

शायद मुझे स्पष्ट याद आ रही है, लेकिन आपकी क्वेरी और क्या अंतर है SELECT nid FROM node WHERE language != 'ab'?
Елин Й

जवाबों:


38

विशिष्ट उदाहरण में, आपको बस इस शर्त को लिखना चाहिए:

$query->condition('n.language', 'ab', '<>');

जेनेरिक मामले में, जहां आपको एक सब-क्वेरी से लौटाए गए मानों पर आधारित डेटाबेस में पंक्तियों का चयन करने की आवश्यकता होती है, आपको इस पर विचार करना चाहिए:

एकमात्र तरीका मैं "सब में" ऑपरेटर का उपयोग करने के लिए उप-क्वेरी के साथ देख सकता हूं condition:

  • सरणी प्राप्त करने के लिए सबक्वेरी निष्पादित करें
  • निम्नलिखित स्निपेट में स्थिति सेट करने वाली मुख्य क्वेरी निष्पादित करें

    $query->condition($key, $subquery_result, 'NOT IN');

    $subquery_result वह सरणी है, जिसमें उप-क्वेरी का परिणाम होता है।

अन्यथा, आप where()दूसरों के कहे अनुसार उपयोग कर सकते हैं , जो आपके द्वारा जोड़े जाने वाले क्वेरी के भाग के लिए एक स्ट्रिंग को स्वीकार करता है।

ध्यान रखें कि db_select()यह धीमा है db_query(); जब आप जानते हैं कि अन्य मॉड्यूल द्वारा परिवर्तन किया जा सकता है तो आपको पहले का उपयोग करना चाहिए। अन्यथा, यदि अन्य मॉड्यूल hook_query_alter()आपकी क्वेरी को बदलने के लिए उपयोग करने वाले नहीं हैं , तो आपको उपयोग करना चाहिए db_query()
नोड्स तक पहुंचने के मामले में, यदि आपको केवल उन नोड्स को प्राप्त करने की आवश्यकता है, जिनके लिए उपयोगकर्ता की पहुंच है, तो आपको क्वेरी के टैग के रूप में उपयोग करने db_select()और जोड़ने की आवश्यकता है । उदाहरण के लिए, निम्न कोड का उपयोग करता है।'node_access'SelectQuery::addTag()blog_page_last()

  $query = db_select('node', 'n')->extend('PagerDefault');
  $nids = $query
  ->fields('n', array('nid', 'sticky', 'created'))
    ->condition('type', 'blog')
    ->condition('status', 1)
    ->orderBy('sticky', 'DESC')
    ->orderBy('created', 'DESC')
    ->limit(variable_get('default_nodes_main', 10))
    ->addTag('node_access')
    ->execute()
    ->fetchCol();

इसी तरह के कोड का उपयोग किया जाता है book_block_view()

$select = db_select('node', 'n')
  ->fields('n', array('title'))
  ->condition('n.nid', $node->book['bid'])
  ->addTag('node_access');
$title = $select->execute()->fetchField();

यहाँ एक दृश्य के लिए एक उपशमन का उदाहरण है कस्टम फ़िल्टर मैंने लिखा है: लिंक
रोजर

1
"Subselects DBTNG परिस्थितियों में काम नहीं करते हैं, जब में के लिए मूल्य के रूप में इस्तेमाल को छोड़कर" ड्रुपल 8.3 में तय हो गई है
जोनाथन

3

जटिल प्रश्न लिखते समय आपको db_query()इसके बजाय निश्चित रूप से उपयोग करना चाहिए db_select()

  1. आप NOT INवर्तमान Drupal डेटाबेस API के साथ एक उपश्रेणी के साथ एक क्लॉज नहीं लिख सकते हैं (यह एक काम कर रहा मुद्दा है)।
  2. यदि आपको अपनी क्वेरी को गतिशील बनाने की आवश्यकता नहीं है (इसलिए अन्य मॉड्यूल द्वारा फिर से लिखा गया है), तो इस तरह के एक जटिल के साथ लिखने की कोशिश करें db_select()
  3. उपश्रेणियाँ अभी तक अच्छी तरह से समर्थित नहीं हैं ( मेरा एक पिछला उत्तर देखें ) और यदि आप एसक्यूएल लिखने के लिए उपयोग किए जाते हैं तो इसका उपयोग करना आसान है db_query()

आपकी क्वेरी के बारे में, मुझे यकीन नहीं है कि आप एक सबक्वेरी का उपयोग क्यों करना चाहते हैं (जब तक कि आप अपनी छूट को सरल नहीं करते)? आप इसे इस तरह आसानी से लिख सकते हैं:

SELECT nid 
FROM node n INNER JOIN languages l ON n.language = l.language
WHERE language NOT IN ('ab')

DISTINCTआवश्यक नहीं है क्योंकि nidयह एक प्राथमिक कुंजी है इसलिए इसे दोहराया नहीं जाएगा।


2
# 2 के संबंध में, ओपी नोड्स का चयन कर रहा है। AFAIK db_select () किसी भी आवश्यक 'नोड_केस' टैग को प्रदान करने का एकमात्र तरीका है, जिसमें केवल db_select () ही विकल्प होगा।
कीथम

2

वहाँ भी है जहाँ () जो एक मनमाना जोड़ने के लिए अनुमति देता है जहां क्वेरी के लिए शर्त।

उदाहरण:

$query->where('n.language NOT IN (SELECT language FROMlanguages WHERE language = :lang)', array(':lang' => $value));

जैसा कि कीथम ने उल्लेख किया है, आपको नोड्स का चयन करते समय db_select () और addTag ('node_access') का उपयोग करना होगा जो तब उपयोगकर्ताओं को प्रदर्शित किए जाते हैं।


1

Db_select को NOT Not subselect के साथ उपयोग करने का एक आसान तरीका बस थोड़ा ज्ञात उपयोग करना है

$ Query-> जहां

एक मनमाना जोड़ने के लिए जहां हालत।

उदाहरण के लिए:

  // 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));  
  $count = $query->countQuery()->execute()->fetchField();
  drupal_set_message($count);

0

जहाँ $ subquery_values ​​$ key => $ nid प्रारूप की एक सरणी है जो एक सबक्वेरी के परिणाम के रूप में है

$query->condition('node.nid', array_values($subquery_values), "NOT IN");

यह बढ़िया काम करता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.