mysql - कई टेबल से SQL क्वेरी वापसी डेटा




select (4)

मैं निम्नलिखित जानना चाहता हूं:

  • मेरे डेटाबेस में एकाधिक टेबल से डेटा कैसे प्राप्त करें?
  • ऐसा करने के लिए किस तरह के तरीके हैं?
  • जुड़वां और संघ क्या हैं और वे एक-दूसरे से अलग कैसे हैं?
  • दूसरों की तुलना में मुझे प्रत्येक का उपयोग कब करना चाहिए?

मैं इसे अपने (उदाहरण के लिए - PHP) एप्लिकेशन में उपयोग करने की योजना बना रहा हूं, लेकिन डेटाबेस के खिलाफ कई प्रश्नों को चलाने के लिए नहीं चाहता हूं, मुझे एक ही क्वेरी में एकाधिक तालिकाओं से डेटा प्राप्त करने के लिए क्या विकल्प हैं?

नोट: मैं इसे लिख रहा हूं क्योंकि मैं कई प्रश्नों पर एक अच्छी तरह लिखित मार्गदर्शिका से लिंक करने में सक्षम होना चाहता हूं जो मैं लगातार PHP कतार में आती हूं, इसलिए जब मैं उत्तर पोस्ट करता हूं तो मैं इसे और विस्तार से लिंक कर सकता हूं।

उत्तर निम्नलिखित को कवर करते हैं:

  1. भाग 1 - जॉइन और यूनियन
  2. भाग 2 - सबक्विरीज़
  3. भाग 3 - चालें और कुशल कोड
  4. भाग 4 - खंड से उपखंड
  5. भाग 5 - जॉन की चाल का मिश्रित थैला

भाग 1 - जॉइन और यूनियन

यह उत्तर शामिल है:

  1. भाग 1
    • आंतरिक जुड़ने का उपयोग करके दो या दो से अधिक तालिकाओं में शामिल होना (अतिरिक्त जानकारी के लिए विकिपीडिया प्रविष्टि देखें)
    • यूनियन क्वेरी का उपयोग कैसे करें
    • बाएं और दाएं बाहरी जुड़ते हैं (यह स्टैक ओवरफ्लो उत्तर जुड़ने के प्रकारों का वर्णन करने के लिए उत्कृष्ट है)
    • अंतर पूछे जाने वाले प्रश्न (और यदि आपका डेटाबेस उनका समर्थन नहीं करता है तो उन्हें पुन: उत्पन्न करने के लिए) - यह SQL-Server ( जानकारी देखें ) का एक फ़ंक्शन है और इस कारण मैंने पहली चीज़ को पहली बार लिखा था
  2. भाग 2
    • उप-सामान - वे क्या हैं, जहां उनका उपयोग किया जा सकता है और क्या देखना है
    • कार्टेसियन AKA में शामिल हो - ओह, दुख!

डेटाबेस में एकाधिक तालिकाओं से डेटा पुनर्प्राप्त करने के कई तरीके हैं। इस जवाब में, मैं एएनएसआई-9 2 सिंटैक्स में शामिल हो जाऊंगा। यह पुराने एएनएसआई -8 9 सिंटैक्स का उपयोग करने वाले कई अन्य ट्यूटोरियल से भिन्न हो सकता है (और यदि आप 89 तक उपयोग करते हैं, तो बहुत कम सहज महसूस हो सकता है - लेकिन मैं बस इतना कह सकता हूं कि यह कोशिश करना है) क्योंकि यह बहुत आसान है समझने के लिए जब प्रश्न अधिक जटिल हो जाते हैं। इसका इस्तेमाल क्यों करें? क्या कोई प्रदर्शन लाभ है? संक्षिप्त जवाब नहीं है, लेकिन इसका उपयोग करने के बाद इसे पढ़ना आसान है। इस वाक्यविन्यास का उपयोग करके अन्य लोगों द्वारा लिखित प्रश्नों को पढ़ना आसान है।

मैं एक छोटे से कैरर्ड की अवधारणा का उपयोग करने जा रहा हूं जिसमें एक ट्रैक है जो यह ट्रैक रखने के लिए डेटाबेस है कि यह कौन सी कारें उपलब्ध है। मालिक ने आपको अपने आईटी कंप्यूटर लड़के के रूप में काम पर रखा है और उम्मीद है कि आप उसे टोपी छोड़ने के लिए पूछे जाने वाले डेटा को छोड़ने में सक्षम होंगे।

मैंने कई लुकअप टेबल बनाए हैं जिनका उपयोग अंतिम तालिका द्वारा किया जाएगा। यह हमें काम करने के लिए एक उचित मॉडल देगा। शुरू करने के लिए, मैं एक उदाहरण डेटाबेस के खिलाफ अपने प्रश्नों को चला रहा हूं जिसमें निम्न संरचना है। मैं उन सामान्य गलतियों के बारे में सोचने की कोशिश करूंगा जो शुरू होते हैं और समझाते हैं कि उनके साथ क्या गलत है - साथ ही साथ यह भी दिखाया जा रहा है कि उन्हें कैसे ठीक किया जाए।

पहली तालिका बस एक रंग सूची है ताकि हम जान सकें कि हमारे पास कार यार्ड में कौन से रंग हैं।

mysql> create table colors(id int(3) not null auto_increment primary key, 
    -> color varchar(15), paint varchar(10));
Query OK, 0 rows affected (0.01 sec)

mysql> show columns from colors;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(3)      | NO   | PRI | NULL    | auto_increment |
| color | varchar(15) | YES  |     | NULL    |                |
| paint | varchar(10) | YES  |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)

mysql> insert into colors (color, paint) values ('Red', 'Metallic'), 
    -> ('Green', 'Gloss'), ('Blue', 'Metallic'), 
    -> ('White' 'Gloss'), ('Black' 'Gloss');
Query OK, 5 rows affected (0.00 sec)
Records: 5  Duplicates: 0  Warnings: 0

mysql> select * from colors;
+----+-------+----------+
| id | color | paint    |
+----+-------+----------+
|  1 | Red   | Metallic |
|  2 | Green | Gloss    |
|  3 | Blue  | Metallic |
|  4 | White | Gloss    |
|  5 | Black | Gloss    |
+----+-------+----------+
5 rows in set (0.00 sec)

ब्रांड टेबल कारों के विभिन्न ब्रांडों को पहचानता है जो कैरीर्ड संभवतः बेच सकते हैं।

mysql> create table brands (id int(3) not null auto_increment primary key, 
    -> brand varchar(15));
Query OK, 0 rows affected (0.01 sec)

mysql> show columns from brands;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(3)      | NO   | PRI | NULL    | auto_increment |
| brand | varchar(15) | YES  |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
2 rows in set (0.01 sec)

mysql> insert into brands (brand) values ('Ford'), ('Toyota'), 
    -> ('Nissan'), ('Smart'), ('BMW');
Query OK, 5 rows affected (0.00 sec)
Records: 5  Duplicates: 0  Warnings: 0

mysql> select * from brands;
+----+--------+
| id | brand  |
+----+--------+
|  1 | Ford   |
|  2 | Toyota |
|  3 | Nissan |
|  4 | Smart  |
|  5 | BMW    |
+----+--------+
5 rows in set (0.00 sec)

मॉडल टेबल विभिन्न प्रकार की कारों को कवर करेगी, वास्तविक कार मॉडल के बजाए विभिन्न कार प्रकारों का उपयोग करने के लिए यह आसान होगा।

mysql> create table models (id int(3) not null auto_increment primary key, 
    -> model varchar(15));
Query OK, 0 rows affected (0.01 sec)

mysql> show columns from models;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(3)      | NO   | PRI | NULL    | auto_increment |
| model | varchar(15) | YES  |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)

mysql> insert into models (model) values ('Sports'), ('Sedan'), ('4WD'), ('Luxury');
Query OK, 4 rows affected (0.00 sec)
Records: 4  Duplicates: 0  Warnings: 0

mysql> select * from models;
+----+--------+
| id | model  |
+----+--------+
|  1 | Sports |
|  2 | Sedan  |
|  3 | 4WD    |
|  4 | Luxury |
+----+--------+
4 rows in set (0.00 sec)

और अंत में, इन सभी अन्य तालिकाओं को बांधने के लिए, वह तालिका जो सब कुछ एक साथ संबंध रखती है। आईडी फ़ील्ड वास्तव में कारों की पहचान करने के लिए उपयोग की जाने वाली अद्वितीय संख्या है।

mysql> create table cars (id int(3) not null auto_increment primary key, 
    -> color int(3), brand int(3), model int(3));
Query OK, 0 rows affected (0.01 sec)

mysql> show columns from cars;
+-------+--------+------+-----+---------+----------------+
| Field | Type   | Null | Key | Default | Extra          |
+-------+--------+------+-----+---------+----------------+
| id    | int(3) | NO   | PRI | NULL    | auto_increment |
| color | int(3) | YES  |     | NULL    |                |
| brand | int(3) | YES  |     | NULL    |                |
| model | int(3) | YES  |     | NULL    |                |
+-------+--------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

mysql> insert into cars (color, brand, model) values (1,2,1), (3,1,2), (5,3,1), 
    -> (4,4,2), (2,2,3), (3,5,4), (4,1,3), (2,2,1), (5,2,3), (4,5,1);
Query OK, 10 rows affected (0.00 sec)
Records: 10  Duplicates: 0  Warnings: 0

mysql> select * from cars;
+----+-------+-------+-------+
| id | color | brand | model |
+----+-------+-------+-------+
|  1 |     1 |     2 |     1 |
|  2 |     3 |     1 |     2 |
|  3 |     5 |     3 |     1 |
|  4 |     4 |     4 |     2 |
|  5 |     2 |     2 |     3 |
|  6 |     3 |     5 |     4 |
|  7 |     4 |     1 |     3 |
|  8 |     2 |     2 |     1 |
|  9 |     5 |     2 |     3 |
| 10 |     4 |     5 |     1 |
+----+-------+-------+-------+
10 rows in set (0.00 sec)

यह हमें विभिन्न प्रकार के जॉइन के नीचे दिए गए उदाहरणों को कवर करने के लिए पर्याप्त डेटा (मुझे आशा है) और उन्हें सार्थक बनाने के लिए पर्याप्त डेटा भी देगा।

तो इसके गले में आना, मालिक जानना चाहता है कि उसके पास सभी स्पोर्ट्स कारों की आईडी है

यह एक साधारण दो टेबल में शामिल है। हमारे पास एक सारणी है जो मॉडल और तालिका को उसमें उपलब्ध स्टॉक के साथ पहचानती है। जैसा कि आप देख सकते हैं, cars तालिका के model कॉलम में डेटा हमारे पास cars टेबल के models कॉलम से संबंधित है। अब, हम जानते हैं कि मॉडल टेबल में Sports लिए 1 आईडी है, इसलिए शामिल होने दें।

select
    ID,
    model
from
    cars
        join models
            on model=ID

तो यह सवाल अच्छा दिखता है? हमने दो तालिकाओं की पहचान की है और हमें आवश्यक जानकारी शामिल है और उसमें शामिल होने का उपयोग करें जो सही ढंग से पहचानता है कि कौन से कॉलम शामिल हों।

ERROR 1052 (23000): Column 'ID' in field list is ambiguous

अरे नहीं! हमारी पहली क्वेरी में एक त्रुटि! हाँ, और यह एक बेर है। आप देखते हैं, क्वेरी को वास्तव में सही कॉलम मिल गए हैं, लेकिन उनमें से कुछ दोनों टेबलों में मौजूद हैं, इसलिए डेटाबेस किस वास्तविक कॉलम का मतलब है और कहां से भ्रमित हो जाता है। इसे हल करने के दो समाधान हैं। पहला अच्छा और सरल है, हम डेटाबेस नाम को बिल्कुल बताने के लिए tableName.columnName का उपयोग कर सकते हैं, इसका अर्थ यह है कि:

select
    cars.ID,
    models.model
from
    cars
        join models
            on cars.model=models.ID

+----+--------+
| ID | model  |
+----+--------+
|  1 | Sports |
|  3 | Sports |
|  8 | Sports |
| 10 | Sports |
|  2 | Sedan  |
|  4 | Sedan  |
|  5 | 4WD    |
|  7 | 4WD    |
|  9 | 4WD    |
|  6 | Luxury |
+----+--------+
10 rows in set (0.00 sec)

दूसरा शायद अधिक बार उपयोग किया जाता है और इसे टेबल एलियासिंग कहा जाता है। इस उदाहरण की तालिकाओं में अच्छे और छोटे सरल नाम हैं, लेकिन KPI_DAILY_SALES_BY_DEPARTMENT जैसे कुछ टाइप करना संभवतः पुराना हो जाएगा, इसलिए इस तरह की तालिका उपनाम करने का एक आसान तरीका है:

select
    a.ID,
    b.model
from
    cars a
        join models b
            on a.model=b.ID

अब, अनुरोध पर वापस। जैसा कि आप देख सकते हैं कि हमारे पास हमारी आवश्यक जानकारी है, लेकिन हमारे पास ऐसी जानकारी भी है जिसके लिए नहीं पूछा गया था, इसलिए हमें केवल स्पोर्ट्स कारों के बारे में पूछे जाने के लिए कथन में एक खंड शामिल करना होगा। जैसा कि मैं टेबल नामों का उपयोग करने के बजाय तालिका उपनाम विधि को प्राथमिकता देता हूं, मैं इस बिंदु से इसके आगे चिपके रहूंगा।

जाहिर है, हमें अपनी क्वेरी में एक क्लॉज जोड़ने की जरूरत है। हम या तो ID=1 या model='Sports' द्वारा स्पोर्ट्स कारों की पहचान कर सकते हैं। चूंकि आईडी अनुक्रमित है और प्राथमिक कुंजी (और यह कम टाइपिंग होती है), आइए हम इसकी क्वेरी में उपयोग करें।

select
    a.ID,
    b.model
from
    cars a
        join models b
            on a.model=b.ID
where
    b.ID=1

+----+--------+
| ID | model  |
+----+--------+
|  1 | Sports |
|  3 | Sports |
|  8 | Sports |
| 10 | Sports |
+----+--------+
4 rows in set (0.00 sec)

बिंगो! बॉस खुश है। बेशक, एक मालिक होने के नाते और जो भी उसने पूछा उससे खुश नहीं होता, वह जानकारी देखता है, फिर कहता है कि मैं रंग भी चाहता हूं

ठीक है, इसलिए हमारे पास पहले से ही लिखी गई हमारी क्वेरी का एक अच्छा हिस्सा है, लेकिन हमें रंगों की एक तीसरी तालिका का उपयोग करने की आवश्यकता है। अब, हमारी मुख्य सूचना तालिका cars कार रंग आईडी स्टोर करती है और यह रंग आईडी कॉलम पर वापस लिंक करती है। तो, मूल रूप से इसी तरह, हम एक तीसरी तालिका में शामिल हो सकते हैं:

select
    a.ID,
    b.model
from
    cars a
        join models b
            on a.model=b.ID
        join colors c
            on a.color=c.ID
where
    b.ID=1

+----+--------+
| ID | model  |
+----+--------+
|  1 | Sports |
|  3 | Sports |
|  8 | Sports |
| 10 | Sports |
+----+--------+
4 rows in set (0.00 sec)

अरे, हालांकि तालिका सही ढंग से शामिल हो गई थी और संबंधित कॉलम जुड़े हुए थे, हम नई तालिका से वास्तविक जानकारी को खींचना भूल गए थे जिसे हमने अभी जोड़ा है।

select
    a.ID,
    b.model,
    c.color
from
    cars a
        join models b
            on a.model=b.ID
        join colors c
            on a.color=c.ID
where
    b.ID=1

+----+--------+-------+
| ID | model  | color |
+----+--------+-------+
|  1 | Sports | Red   |
|  8 | Sports | Green |
| 10 | Sports | White |
|  3 | Sports | Black |
+----+--------+-------+
4 rows in set (0.00 sec)

ठीक है, यह एक पल के लिए हमारी पीठ से मालिक है। अब, कुछ और विस्तार से इसकी व्याख्या करने के लिए। जैसा कि आप देख सकते हैं, हमारे कथन में from खंड हमारी मुख्य तालिका को जोड़ता है (मैं अक्सर एक तालिका का उपयोग करता हूं जिसमें लुकअप या आयाम तालिका की बजाय जानकारी होती है। क्वेरी सभी के साथ स्विच की गई टेबल के साथ ही काम करेगी, लेकिन कम समझ में आती है जब हम कुछ महीनों में इसे पढ़ने के लिए इस प्रश्न पर वापस आते हैं, तो अक्सर एक प्रश्न लिखने का प्रयास करना सबसे अच्छा होता है जो समझने में आसान और समझने में आसान होगा - इसे सहजता से बाहर रखें, अच्छे इंडेंटिंग का उपयोग करें ताकि सब कुछ स्पष्ट हो जैसा कि यह हो सकता है। यदि आप दूसरों को सिखाने के लिए जाते हैं, तो इन विशेषताओं को उनके प्रश्नों में स्थापित करने का प्रयास करें - खासकर अगर आप उन्हें समस्या निवारण करेंगे।

इस तरह से अधिक से अधिक तालिकाओं को जोड़ने के लिए पूरी तरह से संभव है।

select
    a.ID,
    b.model,
    c.color
from
    cars a
        join models b
            on a.model=b.ID
        join colors c
            on a.color=c.ID
        join brands d
            on a.brand=d.ID
where
    b.ID=1

जबकि मैं एक टेबल शामिल करना भूल गया था जहां हम join कथन में एक से अधिक कॉलम में शामिल होना चाहते हैं, यहां एक उदाहरण है। यदि models टेबल में ब्रांड-विशिष्ट मॉडल होते हैं और इसलिए brand नामक कॉलम भी होता है जो ID फ़ील्ड पर brands टेबल पर वापस लिंक होता है, तो इसे इस प्रकार किया जा सकता है:

select
    a.ID,
    b.model,
    c.color
from
    cars a
        join models b
            on a.model=b.ID
        join colors c
            on a.color=c.ID
        join brands d
            on a.brand=d.ID
            and b.brand=d.ID
where
    b.ID=1

आप देख सकते हैं, उपरोक्त क्वेरी न केवल मुख्य cars तालिका में शामिल टेबल को लिंक करती है, बल्कि पहले से जुड़ी तालिकाओं के बीच जुड़ती है। यदि यह नहीं किया गया था, तो परिणाम को एक कार्टशियन शामिल किया जाता है - जिसे डीबीए खराब के लिए बोलता है। एक कार्टेशियन जॉइन वह है जहां पंक्तियां वापस आती हैं क्योंकि जानकारी डेटाबेस को नहीं बताती है कि परिणामों को सीमित कैसे करें, इसलिए क्वेरी मानदंडों के अनुरूप सभी पंक्तियों को वापस लाती है।

तो, एक कार्टशियन शामिल होने का उदाहरण देने के लिए, निम्न क्वेरी चलाएं:

select
    a.ID,
    b.model
from
    cars a
        join models b

+----+--------+
| ID | model  |
+----+--------+
|  1 | Sports |
|  1 | Sedan  |
|  1 | 4WD    |
|  1 | Luxury |
|  2 | Sports |
|  2 | Sedan  |
|  2 | 4WD    |
|  2 | Luxury |
|  3 | Sports |
|  3 | Sedan  |
|  3 | 4WD    |
|  3 | Luxury |
|  4 | Sports |
|  4 | Sedan  |
|  4 | 4WD    |
|  4 | Luxury |
|  5 | Sports |
|  5 | Sedan  |
|  5 | 4WD    |
|  5 | Luxury |
|  6 | Sports |
|  6 | Sedan  |
|  6 | 4WD    |
|  6 | Luxury |
|  7 | Sports |
|  7 | Sedan  |
|  7 | 4WD    |
|  7 | Luxury |
|  8 | Sports |
|  8 | Sedan  |
|  8 | 4WD    |
|  8 | Luxury |
|  9 | Sports |
|  9 | Sedan  |
|  9 | 4WD    |
|  9 | Luxury |
| 10 | Sports |
| 10 | Sedan  |
| 10 | 4WD    |
| 10 | Luxury |
+----+--------+
40 rows in set (0.00 sec)

अच्छा भगवान, वह बदसूरत है। हालांकि, जहां तक ​​डेटाबेस का संबंध है, वही है जो इसके लिए पूछा गया था। पूछताछ में, हमने cars से models और model से models मांग की। हालांकि, क्योंकि हमने टेबल में शामिल होने का तरीका निर्दिष्ट नहीं किया है, इसलिए डेटाबेस ने दूसरी तालिका से प्रत्येक पंक्ति के साथ पहली तालिका से प्रत्येक पंक्ति से मिलान किया है।

ठीक है, तो मालिक वापस आ गया है, और वह फिर से और जानकारी चाहता है। मुझे वही सूची चाहिए, लेकिन इसमें 4WD भी शामिल हैं

हालांकि, यह हमें पूरा करने के दो अलग-अलग तरीकों को देखने का एक बड़ा बहाना देता है। हम इस तरह के खंड में एक और शर्त जोड़ सकते हैं:

select
    a.ID,
    b.model,
    c.color
from
    cars a
        join models b
            on a.model=b.ID
        join colors c
            on a.color=c.ID
        join brands d
            on a.brand=d.ID
where
    b.ID=1
    or b.ID=3

जबकि उपर्युक्त पूरी तरह से काम करेगा, इसे अलग-अलग देखें, यह दिखाने का एक बड़ा बहाना है कि union क्वेरी कैसे काम करेगी।

हम जानते हैं कि निम्नलिखित सभी स्पोर्ट्स कार वापस कर देंगे:

select
    a.ID,
    b.model,
    c.color
from
    cars a
        join models b
            on a.model=b.ID
        join colors c
            on a.color=c.ID
        join brands d
            on a.brand=d.ID
where
    b.ID=1

और निम्नलिखित सभी 4WD वापस आ जाएगा:

select
    a.ID,
    b.model,
    c.color
from
    cars a
        join models b
            on a.model=b.ID
        join colors c
            on a.color=c.ID
        join brands d
            on a.brand=d.ID
where
    b.ID=3

तो union all उनके बीच union all खंड जोड़कर, दूसरी क्वेरी के परिणाम पहली क्वेरी के परिणामों में शामिल किए जाएंगे।

select
    a.ID,
    b.model,
    c.color
from
    cars a
        join models b
            on a.model=b.ID
        join colors c
            on a.color=c.ID
        join brands d
            on a.brand=d.ID
where
    b.ID=1
union all
select
    a.ID,
    b.model,
    c.color
from
    cars a
        join models b
            on a.model=b.ID
        join colors c
            on a.color=c.ID
        join brands d
            on a.brand=d.ID
where
    b.ID=3

+----+--------+-------+
| ID | model  | color |
+----+--------+-------+
|  1 | Sports | Red   |
|  8 | Sports | Green |
| 10 | Sports | White |
|  3 | Sports | Black |
|  5 | 4WD    | Green |
|  7 | 4WD    | White |
|  9 | 4WD    | Black |
+----+--------+-------+
7 rows in set (0.00 sec)

जैसा कि आप देख सकते हैं, पहली क्वेरी के परिणाम पहले लौटाए जाते हैं, इसके बाद दूसरी क्वेरी के परिणाम होते हैं।

इस उदाहरण में, यह निश्चित रूप से पहली क्वेरी का उपयोग करना बहुत आसान होगा, लेकिन विशिष्ट मामलों के लिए union प्रश्न बहुत अच्छे हो सकते हैं। वे टेबल से टेबल से विशिष्ट परिणामों को वापस करने का एक शानदार तरीका हैं जो आसानी से एक साथ नहीं जुड़े होते हैं - या उस मामले के लिए पूरी तरह से असंबंधित तालिकाओं के लिए। हालांकि पालन करने के लिए कुछ नियम हैं।

  • पहली क्वेरी से कॉलम प्रकार नीचे दिए गए प्रत्येक अन्य क्वेरी से कॉलम प्रकारों से मेल खाते हैं।
  • पहली क्वेरी से कॉलम के नाम का उपयोग परिणामों के पूरे सेट की पहचान के लिए किया जाएगा।
  • प्रत्येक क्वेरी में कॉलम की संख्या समान होनी चाहिए।

अब, आप सोच रहे होंगे कि union और union all का उपयोग करने के बीच क्या अंतर है। एक union क्वेरी डुप्लिकेट को हटा देगी, जबकि एक union all नहीं करेगा। इसका मतलब यह है कि union पर union all का उपयोग करते समय एक छोटा सा प्रदर्शन मारा जाता है लेकिन परिणाम इसके लायक हो सकते हैं - हालांकि मैं इस तरह की चीज़ों पर अनुमान लगाऊंगा।

इस नोट पर, यहां कुछ अतिरिक्त नोट्स को ध्यान देने योग्य हो सकता है।

  • अगर हम परिणामों को ऑर्डर करना चाहते हैं, तो हम एक order by उपयोग कर सकते हैं लेकिन आप उपनाम का उपयोग नहीं कर सकते हैं। उपर्युक्त क्वेरी में, order by a.ID परिणामस्वरूप एक त्रुटि होगी - जहां तक ​​परिणाम संबंधित हैं, कॉलम को a.ID बजाय ID कहा जाता है - भले ही समान प्रश्नों का उपयोग दोनों प्रश्नों में किया गया हो।
  • हम केवल कथन order by एक order by प्राप्त कर सकते हैं, और यह अंतिम बयान के रूप में होना चाहिए।

अगले उदाहरणों के लिए, मैं अपनी टेबल पर कुछ अतिरिक्त पंक्तियां जोड़ रहा हूं।

मैंने Holden टेबल में Holden को जोड़ा है। मैंने cars में एक पंक्ति भी जोड़ दी है जिसमें 12 का color मान है - जिसमें रंग तालिका में कोई संदर्भ नहीं है।

ठीक है, बॉस फिर से वापस आ गया है, अनुरोधों को भौंकने वाला - * मैं अपने द्वारा उठाए गए प्रत्येक ब्रांड की गिनती और इसमें कारों की संख्या चाहता हूं! '- विशिष्ट, हम सिर्फ हमारी चर्चा का एक दिलचस्प अनुभाग प्राप्त करते हैं और मालिक अधिक काम करना चाहता है ।

राइटो, तो सबसे पहले हमें जो करना है वह संभावित ब्रांडों की पूरी सूची प्राप्त करना है।

select
    a.brand
from
    brands a

+--------+
| brand  |
+--------+
| Ford   |
| Toyota |
| Nissan |
| Smart  |
| BMW    |
| Holden |
+--------+
6 rows in set (0.00 sec)

अब, जब हम अपनी कार टेबल में शामिल होते हैं तो हमें निम्न परिणाम मिलते हैं:

select
    a.brand
from
    brands a
        join cars b
            on a.ID=b.brand
group by
    a.brand

+--------+
| brand  |
+--------+
| BMW    |
| Ford   |
| Nissan |
| Smart  |
| Toyota |
+--------+
5 rows in set (0.00 sec)

निश्चित रूप से एक समस्या है - हम जोड़े गए सुंदर Holden ब्रांड का कोई उल्लेख नहीं देख रहे हैं।

ऐसा इसलिए है क्योंकि एक जॉइन दोनों तालिकाओं में मिलान पंक्तियों के लिए दिखता है। चूंकि Holden की तरह कारों में कोई डेटा नहीं है, यह वापस नहीं किया जाता है। यह वह जगह है जहां हम outer शामिल हो सकते हैं। यह सभी परिणामों को एक तालिका से वापस कर देगा चाहे वे अन्य तालिका में मेल खाते हों या नहीं:

select
    a.brand
from
    brands a
        left outer join cars b
            on a.ID=b.brand
group by
    a.brand

+--------+
| brand  |
+--------+
| BMW    |
| Ford   |
| Holden |
| Nissan |
| Smart  |
| Toyota |
+--------+
6 rows in set (0.00 sec)

अब हमारे पास यह है कि, हम एक गिनती पाने के लिए एक सुंदर कुल कार्य जोड़ सकते हैं और एक पल के लिए मालिक को हमारी पीठ से दूर कर सकते हैं।

select
    a.brand,
    count(b.id) as countOfBrand
from
    brands a
        left outer join cars b
            on a.ID=b.brand
group by
    a.brand

+--------+--------------+
| brand  | countOfBrand |
+--------+--------------+
| BMW    |            2 |
| Ford   |            2 |
| Holden |            0 |
| Nissan |            1 |
| Smart  |            1 |
| Toyota |            5 |
+--------+--------------+
6 rows in set (0.00 sec)

और उसके साथ, बॉस skulks दूर।

अब, इसे और अधिक विस्तार से समझाओ, बाहरी जुड़ने left या right प्रकार के हो सकते हैं। बाएं या दाएं परिभाषित करता है कि कौन सी तालिका पूरी तरह से शामिल है। left outer join में बायीं तरफ टेबल की सभी पंक्तियां left outer join होंगी, जबकि (आपने अनुमान लगाया है) एक right outer join परिणामों के दाईं ओर तालिका से सभी परिणामों को लाता है।

कुछ डेटाबेस एक full outer join अनुमति देंगे जो दोनों तालिकाओं से परिणाम (चाहे मिलान किया गया हो या नहीं) लाएगा, लेकिन यह सभी डेटाबेस में समर्थित नहीं है।

अब, मैं शायद इस समय इस बिंदु पर आंकड़ा हूं, आप सोच रहे हैं कि आप किसी प्रश्न में शामिल प्रकारों को मर्ज कर सकते हैं या नहीं - और जवाब हाँ है, आप बिल्कुल कर सकते हैं।

select
    b.brand,
    c.color,
    count(a.id) as countOfBrand
from
    cars a
        right outer join brands b
            on b.ID=a.brand
        join colors c
            on a.color=c.ID
group by
    a.brand,
    c.color

+--------+-------+--------------+
| brand  | color | countOfBrand |
+--------+-------+--------------+
| Ford   | Blue  |            1 |
| Ford   | White |            1 |
| Toyota | Black |            1 |
| Toyota | Green |            2 |
| Toyota | Red   |            1 |
| Nissan | Black |            1 |
| Smart  | White |            1 |
| BMW    | Blue  |            1 |
| BMW    | White |            1 |
+--------+-------+--------------+
9 rows in set (0.00 sec)

तो, वह परिणाम क्यों नहीं थे? ऐसा इसलिए है क्योंकि यद्यपि हमने कारों से ब्रांडों में बाहरी शामिल होने का चयन किया है, लेकिन इसे रंगों में शामिल होने में निर्दिष्ट नहीं किया गया था - ताकि विशेष रूप से शामिल होने से केवल उन दोनों परिणामों को वापस लाया जा सके जो दोनों तालिकाओं में मेल खाते हैं।

यहां वह प्रश्न है जो हमारे द्वारा अपेक्षित परिणामों को प्राप्त करने के लिए काम करेगा:

select
    a.brand,
    c.color,
    count(b.id) as countOfBrand
from
    brands a
        left outer join cars b
            on a.ID=b.brand
        left outer join colors c
            on b.color=c.ID
group by
    a.brand,
    c.color

+--------+-------+--------------+
| brand  | color | countOfBrand |
+--------+-------+--------------+
| BMW    | Blue  |            1 |
| BMW    | White |            1 |
| Ford   | Blue  |            1 |
| Ford   | White |            1 |
| Holden | NULL  |            0 |
| Nissan | Black |            1 |
| Smart  | White |            1 |
| Toyota | NULL  |            1 |
| Toyota | Black |            1 |
| Toyota | Green |            2 |
| Toyota | Red   |            1 |
+--------+-------+--------------+
11 rows in set (0.00 sec)

जैसा कि हम देख सकते हैं, हमारे पास क्वेरी में दो बाहरी शामिल हैं और परिणाम अपेक्षित के माध्यम से आ रहे हैं।

अब, उन अन्य प्रकार के जुड़ने के बारे में आप कैसे पूछते हैं? चौराहे के बारे में क्या?

खैर, सभी डेटाबेस intersection समर्थन नहीं करते हैं लेकिन बहुत सारे डेटाबेस आपको शामिल होने के माध्यम से एक छेड़छाड़ करने की अनुमति देंगे (या कम से कम एक अच्छी तरह से संरचित जहां कथन)।

एक छेड़छाड़ ऊपर वर्णित अनुसार union समान कुछ प्रकार का जुड़ाव है - लेकिन अंतर यह है कि यह केवल यूनियन द्वारा जुड़े विभिन्न व्यक्तिगत प्रश्नों के बीच समान डेटा (और मेरा समान मतलब है) की पंक्तियां देता है। केवल हर पंक्ति में समान पंक्तियां लौटा दी जाएंगी।

एक साधारण उदाहरण इस प्रकार होगा:

select
    *
from
    colors
where
    ID>2
intersect
select
    *
from
    colors
where
    id<4

जबकि एक सामान्य union क्वेरी तालिका के सभी पंक्तियों को वापस कर देगी (पहली क्वेरी ID>2 पर कुछ भी लौटाती है और दूसरी ID<4 ) होती है जिसके परिणामस्वरूप पूर्ण सेट होता है, एक अंतर पूछताछ केवल पंक्ति मिलान id=3 वापस कर देगी id=3 क्योंकि यह दोनों मानदंडों को पूरा करता है।

अब, यदि आपका डेटाबेस एक intersect क्वेरी का समर्थन नहीं करता है, तो उपर्युक्त निम्नलिखित क्वेरी के साथ आसानी से जोड़ा जा सकता है:

select
    a.ID,
    a.color,
    a.paint
from
    colors a
        join colors b
            on a.ID=b.ID
where
    a.ID>2
    and b.ID<4

+----+-------+----------+
| ID | color | paint    |
+----+-------+----------+
|  3 | Blue  | Metallic |
+----+-------+----------+
1 row in set (0.00 sec)

यदि आप एक डेटाबेस का उपयोग करके दो अलग-अलग तालिकाओं में एक चौराहे करना चाहते हैं जो अंतर्निहित क्वेरी का स्वाभाविक रूप से समर्थन नहीं करता है, तो आपको तालिकाओं के प्रत्येक कॉलम पर शामिल होना होगा।


भाग 2 - सबक्विरीज़

ठीक है, अब बॉस फिर से फट गया है - मैं ब्रांड के साथ हमारी सभी कारों की एक सूची चाहता हूं और हमारे पास कितने ब्रांड हैं!

एसक्यूएल गुड्स - सबक्वायरी के हमारे बैग में अगली चाल का उपयोग करने का यह एक शानदार अवसर है। यदि आप इस शब्द से अपरिचित हैं, तो एक सबक्वायरी एक क्वेरी है जो किसी अन्य क्वेरी के अंदर चलती है। उनका उपयोग करने के कई अलग-अलग तरीके हैं।

हमारे अनुरोध के लिए, पहले एक साथ एक साधारण क्वेरी डालें जो प्रत्येक कार और ब्रांड को सूचीबद्ध करेगी:

select
    a.ID,
    b.brand
from
    cars a
        join brands b
            on a.brand=b.ID

अब, अगर हम ब्रांड द्वारा क्रमबद्ध कारों की गिनती करना चाहते हैं, तो हम निश्चित रूप से इसे लिख सकते हैं:

select
    b.brand,
    count(a.ID) as countCars
from
    cars a
        join brands b
            on a.brand=b.ID
group by
    b.brand

+--------+-----------+
| brand  | countCars |
+--------+-----------+
| BMW    |         2 |
| Ford   |         2 |
| Nissan |         1 |
| Smart  |         1 |
| Toyota |         5 |
+--------+-----------+

तो, हम केवल हमारी मूल क्वेरी में गिनती फ़ंक्शन में जोड़ने में सक्षम होना चाहिए?

select
    a.ID,
    b.brand,
    count(a.ID) as countCars
from
    cars a
        join brands b
            on a.brand=b.ID
group by
    a.ID,
    b.brand

+----+--------+-----------+
| ID | brand  | countCars |
+----+--------+-----------+
|  1 | Toyota |         1 |
|  2 | Ford   |         1 |
|  3 | Nissan |         1 |
|  4 | Smart  |         1 |
|  5 | Toyota |         1 |
|  6 | BMW    |         1 |
|  7 | Ford   |         1 |
|  8 | Toyota |         1 |
|  9 | Toyota |         1 |
| 10 | BMW    |         1 |
| 11 | Toyota |         1 |
+----+--------+-----------+
11 rows in set (0.00 sec)

अफसोस की बात है, नहीं, हम ऐसा नहीं कर सकते हैं। इसका कारण यह है कि जब हम कार आईडी (कॉलम ए.आईडी) में जोड़ते हैं तो हमें इसे समूह में जोड़ना होता है - इसलिए अब, जब गिनती फ़ंक्शन काम करता है, तो प्रति आईडी से मेल खाने वाली केवल एक आईडी होती है।

यह वह जगह है जहां हम एक सबक्वायरी का उपयोग कर सकते हैं - असल में हम दो पूरी तरह से विभिन्न प्रकार के सबक्वायरी कर सकते हैं जो उसी परिणाम को वापस कर देंगे जो हमें इसके लिए चाहिए। सबसे पहले select खंड में सबक्वायरी डालना है। इसका मतलब यह है कि हर बार जब हमें डेटा की एक पंक्ति मिलती है, तो सबक्वायरी समाप्त हो जाएगी, डेटा का एक स्तंभ प्राप्त करें और फिर इसे डेटा की हमारी पंक्ति में पॉप करें।

select
    a.ID,
    b.brand,
    (
    select
        count(c.ID)
    from
        cars c
    where
        a.brand=c.brand
    ) as countCars
from
    cars a
        join brands b
            on a.brand=b.ID

+----+--------+-----------+
| ID | brand  | countCars |
+----+--------+-----------+
|  2 | Ford   |         2 |
|  7 | Ford   |         2 |
|  1 | Toyota |         5 |
|  5 | Toyota |         5 |
|  8 | Toyota |         5 |
|  9 | Toyota |         5 |
| 11 | Toyota |         5 |
|  3 | Nissan |         1 |
|  4 | Smart  |         1 |
|  6 | BMW    |         2 |
| 10 | BMW    |         2 |
+----+--------+-----------+
11 rows in set (0.00 sec)

और बाम !, यह हमें करेगा। यदि आपने देखा है, तो इस सब क्वेरी को हमारे द्वारा लौटाए गए डेटा की प्रत्येक पंक्ति के लिए चलना होगा। यहां तक ​​कि इस छोटे से उदाहरण में, हमारे पास केवल पांच अलग-अलग ब्रांड हैं, लेकिन सबक्वायरी ग्यारह बार दौड़ गई है क्योंकि हमारे पास डेटा की ग्यारह पंक्तियां हैं जिन्हें हम लौट रहे हैं। इसलिए, इस मामले में, यह कोड लिखने का सबसे प्रभावी तरीका प्रतीत नहीं होता है।

एक अलग दृष्टिकोण के लिए, एक सबक्वायरी चलाएं और दिखाएं कि यह एक सारणी है:

select
    a.ID,
    b.brand,
    d.countCars
from
    cars a
        join brands b
            on a.brand=b.ID
        join
            (
            select
                c.brand,
                count(c.ID) as countCars
            from
                cars c
            group by
                c.brand
            ) d
            on a.brand=d.brand

+----+--------+-----------+
| ID | brand  | countCars |
+----+--------+-----------+
|  1 | Toyota |         5 |
|  2 | Ford   |         2 |
|  3 | Nissan |         1 |
|  4 | Smart  |         1 |
|  5 | Toyota |         5 |
|  6 | BMW    |         2 |
|  7 | Ford   |         2 |
|  8 | Toyota |         5 |
|  9 | Toyota |         5 |
| 10 | BMW    |         2 |
| 11 | Toyota |         5 |
+----+--------+-----------+
11 rows in set (0.00 sec)

ठीक है, तो हमारे पास एक ही परिणाम हैं (थोड़ा अलग आदेश दिया गया - ऐसा लगता है कि डेटाबेस इस बार उठाए गए पहले कॉलम द्वारा आदेशित परिणामों को वापस करना चाहता था) - लेकिन वही सही संख्याएं।

तो, दोनों के बीच क्या अंतर है - और हमें प्रत्येक प्रकार की सबक्वायरी का उपयोग कब करना चाहिए? सबसे पहले, सुनिश्चित करें कि हम समझते हैं कि यह दूसरी क्वेरी कैसे काम करती है। हमने अपनी क्वेरी के खंड from दो तालिकाओं का चयन किया, और फिर एक प्रश्न लिखा और डेटाबेस को बताया कि वास्तव में यह एक टेबल था - जो डेटाबेस पूरी तरह से खुश है। इस विधि (साथ ही कुछ सीमाएं) का उपयोग करने के कुछ फायदे भी हो सकते हैं। सबसे महत्वपूर्ण यह है कि यह सबक्वायरी एक बार भाग गया। यदि हमारे डेटाबेस में डेटा की एक बड़ी मात्रा शामिल है, तो पहले विधि पर बड़े पैमाने पर सुधार हो सकता है। हालांकि, चूंकि हम इसे एक टेबल के रूप में उपयोग कर रहे हैं, हमें डेटा की अतिरिक्त पंक्तियां लाना है - ताकि वे वास्तव में डेटा की हमारी पंक्तियों में शामिल हो सकें। हमें यह भी सुनिश्चित करना होगा कि अगर हम उपरोक्त क्वेरी में एक साधारण शामिल होने का उपयोग करने जा रहे हैं तो डेटा की पर्याप्त पंक्तियां हैं। यदि आपको याद है, तो जॉइन केवल उन पंक्तियों को खींच देगा जिनमें शामिल होने के दोनों किनारों पर मिलान डेटा है। अगर हम सावधान नहीं हैं, तो परिणामस्वरूप हमारे डेटा तालिका से वापस लौटाया जा सकता है यदि इस सबक्वायरी में कोई मिलान पंक्ति नहीं थी।

अब, पहले सबक्वायरी पर वापस देखकर, कुछ सीमाएं भी हैं। क्योंकि हम डेटा को एक पंक्ति में वापस खींच रहे हैं, हम केवल डेटा की एक पंक्ति वापस खींच सकते हैं। किसी क्वेरी के select खंड में उपयोग की जाने वाली सबक्विरी अक्सर sum , count , max या किसी अन्य समान कार्य जैसे कुल कार्य का उपयोग करती है। उन्हें नहीं करना है, लेकिन अक्सर यह लिखा जाता है कि वे कैसे लिखे गए हैं।

इसलिए, आगे बढ़ने से पहले, आइए देखें कि हम एक सबक्वायरी का उपयोग कहां कर सकते हैं। हम इसका उपयोग where कर सकते हैं - अब, यह उदाहरण हमारे डेटाबेस में थोड़ा सा योगदान है, निम्नलिखित डेटा प्राप्त करने के बेहतर तरीके हैं, लेकिन यह देखते हुए कि यह केवल एक उदाहरण के लिए है, देखते हैं:

select
    ID,
    brand
from
    brands
where
    brand like '%o%'

+----+--------+
| ID | brand  |
+----+--------+
|  1 | Ford   |
|  2 | Toyota |
|  6 | Holden |
+----+--------+
3 rows in set (0.00 sec)

यह हमें ब्रांड आईडी और ब्रांड नामों की एक सूची देता है (दूसरा कॉलम केवल हमें ब्रांड दिखाने के लिए जोड़ा जाता है) जिसमें नाम में अक्षर o होता है।

अब, हम इस क्वेरी के परिणामों का उपयोग उस खंड में कर सकते हैं जहां यह खंड है:

select
    a.ID,
    b.brand
from
    cars a
        join brands b
            on a.brand=b.ID
where
    a.brand in
        (
        select
            ID
        from
            brands
        where
            brand like '%o%'
        )

+----+--------+
| ID | brand  |
+----+--------+
|  2 | Ford   |
|  7 | Ford   |
|  1 | Toyota |
|  5 | Toyota |
|  8 | Toyota |
|  9 | Toyota |
| 11 | Toyota |
+----+--------+
7 rows in set (0.00 sec)

जैसा कि आप देख सकते हैं, भले ही सबक्वायरी तीन ब्रांड आईडी लौट रही थी, फिर भी हमारी कार टेबल में उनमें से दो के लिए प्रविष्टियां थीं।

इस मामले में, अधिक जानकारी के लिए, सबक्वायरी काम कर रही है जैसे कि हमने निम्नलिखित कोड लिखा है:

select
    a.ID,
    b.brand
from
    cars a
        join brands b
            on a.brand=b.ID
where
    a.brand in (1,2,6)

+----+--------+
| ID | brand  |
+----+--------+
|  1 | Toyota |
|  2 | Ford   |
|  5 | Toyota |
|  7 | Ford   |
|  8 | Toyota |
|  9 | Toyota |
| 11 | Toyota |
+----+--------+
7 rows in set (0.00 sec)

दोबारा, आप देख सकते हैं कि मैन्युअल इनपुट बनाम एक सबक्वायरी ने डेटाबेस से लौटने पर पंक्तियों के क्रम को कैसे बदल दिया है।

जबकि हम subqueries पर चर्चा कर रहे हैं, देखते हैं कि हम सबक्वायरी के साथ और क्या कर सकते हैं:

  • आप एक और सबक्वायरी के भीतर एक सबक्वायरी डाल सकते हैं, और इसी तरह से। एक सीमा है जो आपके डेटाबेस पर निर्भर करती है, लेकिन कुछ पागल और मनोचिकित्सक प्रोग्रामर के पुनरावर्ती कार्यों से कम, अधिकांश लोग कभी भी उस सीमा को नहीं मारेंगे।
  • आप एक ही क्वेरी में कई उपक्विरी रख सकते हैं, कुछ select खंड में कुछ, खंड from कुछ और where क्लॉज में कुछ और - बस याद रखें कि आपके द्वारा डाला गया प्रत्येक व्यक्ति आपकी क्वेरी को अधिक जटिल बना रहा है और संभवतः निष्पादित करने में अधिक समय लगता है।

यदि आपको कुछ कुशल कोड लिखने की आवश्यकता है, तो क्वेरी को कई तरीकों से लिखना फायदेमंद हो सकता है और देख सकता है (या तो इसे समयबद्ध करके या समझाया योजना का उपयोग करके) जो आपके परिणाम प्राप्त करने के लिए इष्टतम क्वेरी है। काम करने का पहला तरीका हमेशा ऐसा करने का सबसे अच्छा तरीका नहीं हो सकता है।


ठीक है, मुझे यह पोस्ट बहुत दिलचस्प लगता है और मैं एक प्रश्न बनाने पर अपने कुछ ज्ञान साझा करना चाहता हूं। इस Fluffeh के लिए धन्यवाद। जो लोग इसे पढ़ सकते हैं और महसूस कर सकते हैं कि मैं गलत हूं, मेरे उत्तर को संपादित करने और आलोचना करने के लिए 101% स्वतंत्र हैं। ( ईमानदारी से, मैं अपनी गलती को सही करने के लिए बहुत आभारी हूं। )

मैं MySQL टैग में अक्सर पूछे जाने वाले प्रश्नों को पोस्ट कर दूंगा।

ट्रिक नंबर 1 ( पंक्तियां जो कई स्थितियों से मेल खाते हैं )

इस स्कीमा को देखते हुए

CREATE TABLE MovieList
(
    ID INT,
    MovieName VARCHAR(25),
    CONSTRAINT ml_pk PRIMARY KEY (ID),
    CONSTRAINT ml_uq UNIQUE (MovieName)
);

INSERT INTO MovieList VALUES (1, 'American Pie');
INSERT INTO MovieList VALUES (2, 'The Notebook');
INSERT INTO MovieList VALUES (3, 'Discovery Channel: Africa');
INSERT INTO MovieList VALUES (4, 'Mr. Bean');
INSERT INTO MovieList VALUES (5, 'Expendables 2');

CREATE TABLE CategoryList
(
    MovieID INT,
    CategoryName VARCHAR(25),
    CONSTRAINT cl_uq UNIQUE(MovieID, CategoryName),
    CONSTRAINT cl_fk FOREIGN KEY (MovieID) REFERENCES MovieList(ID)
);

INSERT INTO CategoryList VALUES (1, 'Comedy');
INSERT INTO CategoryList VALUES (1, 'Romance');
INSERT INTO CategoryList VALUES (2, 'Romance');
INSERT INTO CategoryList VALUES (2, 'Drama');
INSERT INTO CategoryList VALUES (3, 'Documentary');
INSERT INTO CategoryList VALUES (4, 'Comedy');
INSERT INTO CategoryList VALUES (5, 'Comedy');
INSERT INTO CategoryList VALUES (5, 'Action');

सवाल

कम से कम Comedy और Romance श्रेणियों से संबंधित सभी फिल्में खोजें।

उपाय

यह प्रश्न कभी-कभी बहुत मुश्किल हो सकता है। ऐसा लगता है कि इस तरह की एक क्वेरी जवाब होगा: -

SELECT  DISTINCT a.MovieName
FROM    MovieList a
        INNER JOIN CategoryList b
            ON a.ID = b.MovieID
WHERE   b.CategoryName = 'Comedy' AND
        b.CategoryName = 'Romance'

एसक्यूएलफिल्ड डेमो

जो निश्चित रूप से बहुत गलत है क्योंकि इससे कोई परिणाम नहीं मिलता है । इसका स्पष्टीकरण यह है कि प्रत्येक पंक्ति पर श्रेणीनाम का केवल एक वैध मान है। उदाहरण के लिए, पहली शर्त सच होती है , दूसरी स्थिति हमेशा झूठी होती है। इस प्रकार, AND ऑपरेटर का उपयोग करके, दोनों स्थितियां सत्य होनी चाहिए; अन्यथा, यह झूठा होगा। एक और सवाल इस तरह है,

SELECT  DISTINCT a.MovieName
FROM    MovieList a
        INNER JOIN CategoryList b
            ON a.ID = b.MovieID
WHERE   b.CategoryName IN ('Comedy','Romance')

एसक्यूएलफिल्ड डेमो

और नतीजा अभी भी गलत है क्योंकि यह रिकॉर्ड करने के लिए मेल खाता है कि श्रेणीनाम पर कम से कम एक मैच है। वास्तविक समाधान प्रति फिल्म रिकॉर्ड उदाहरणों की संख्या की गणना करके होगा । उदाहरण की संख्या स्थिति में आपूर्ति किए गए मूल्यों की कुल संख्या से मेल खाना चाहिए।

SELECT  a.MovieName
FROM    MovieList a
        INNER JOIN CategoryList b
            ON a.ID = b.MovieID
WHERE   b.CategoryName IN ('Comedy','Romance')
GROUP BY a.MovieName
HAVING COUNT(*) = 2

एसक्यूएलफिल्ड डेमो (उत्तर)

ट्रिक नंबर 2 ( प्रत्येक प्रविष्टि के लिए अधिकतम रिकॉर्ड )

स्कीमा दिया गया,

CREATE TABLE Software
(
    ID INT,
    SoftwareName VARCHAR(25),
    Descriptions VARCHAR(150),
    CONSTRAINT sw_pk PRIMARY KEY (ID),
    CONSTRAINT sw_uq UNIQUE (SoftwareName)  
);

INSERT INTO Software VALUES (1,'PaintMe','used for photo editing');
INSERT INTO Software VALUES (2,'World Map','contains map of different places of the world');
INSERT INTO Software VALUES (3,'Dictionary','contains description, synonym, antonym of the words');

CREATE TABLE VersionList
(
    SoftwareID INT,
    VersionNo INT,
    DateReleased DATE,
    CONSTRAINT sw_uq UNIQUE (SoftwareID, VersionNo),
    CONSTRAINT sw_fk FOREIGN KEY (SOftwareID) REFERENCES Software(ID)
);

INSERT INTO VersionList VALUES (3, 2, '2009-12-01');
INSERT INTO VersionList VALUES (3, 1, '2009-11-01');
INSERT INTO VersionList VALUES (3, 3, '2010-01-01');
INSERT INTO VersionList VALUES (2, 2, '2010-12-01');
INSERT INTO VersionList VALUES (2, 1, '2009-12-01');
INSERT INTO VersionList VALUES (1, 3, '2011-12-01');
INSERT INTO VersionList VALUES (1, 2, '2010-12-01');
INSERT INTO VersionList VALUES (1, 1, '2009-12-01');
INSERT INTO VersionList VALUES (1, 4, '2012-12-01');

सवाल

प्रत्येक सॉफ्टवेयर पर नवीनतम संस्करण खोजें। निम्नलिखित कॉलम प्रदर्शित करें: SoftwareName , Descriptions , LatestVersion ( LatestVersion नहीं कॉलम से ), DateReleased

उपाय

कुछ एसक्यूएल डेवलपर्स गलती से MAX() कुल फ़ंक्शन का उपयोग करते हैं। वे इस तरह पैदा करते हैं,

SELECT  a.SoftwareName, a.Descriptions,
        MAX(b.VersionNo) AS LatestVersion, b.DateReleased
FROM    Software a
        INNER JOIN VersionList b
            ON a.ID = b.SoftwareID
GROUP BY a.ID
ORDER BY a.ID

एसक्यूएलफिल्ड डेमो

( अधिकांश आरडीबीएमएस इस पर एक वाक्यविन्यास त्रुटि उत्पन्न करता है क्योंकि group by कुछ गैर-समेकित कॉलम निर्दिष्ट नहीं करते हैं ) परिणाम प्रत्येक सॉफ़्टवेयर पर सही LatestVersion उत्पन्न करता है लेकिन स्पष्ट रूप से DateReleased गलत है। MySQL Window Functions और Common Table Expression समर्थन नहीं करता है, क्योंकि कुछ आरडीबीएमएस पहले से ही हैं। इस समस्या पर कामकाज एक subquery बनाना है जो प्रत्येक अधिकतम सॉफ्टवेयर पर व्यक्तिगत अधिकतम versionNo प्राप्त करता है और बाद में अन्य तालिकाओं में शामिल हो जाता है।

SELECT  a.SoftwareName, a.Descriptions,
        b.LatestVersion, c.DateReleased
FROM    Software a
        INNER JOIN
        (
            SELECT  SoftwareID, MAX(VersionNO) LatestVersion
            FROM    VersionList
            GROUP BY SoftwareID
        ) b ON a.ID = b.SoftwareID
        INNER JOIN VersionList c
            ON  c.SoftwareID = b.SoftwareID AND
                c.VersionNO = b.LatestVersion
GROUP BY a.ID
ORDER BY a.ID

एसक्यूएलफिल्ड डेमो (उत्तर)

तो वह था। मैं जल्द ही एक और पोस्टिंग करूँगा क्योंकि मुझे MySQL टैग पर कोई अन्य FAQ याद है। इस छोटे लेख को पढ़ने के लिए धन्यवाद। मुझे आशा है कि आपको कम से कम इस से थोड़ा ज्ञान मिलेगा।

अद्यतन 1

ट्रिक नंबर 3 ( दो आईडी के बीच नवीनतम रिकॉर्ड ढूँढना )

स्कीमा दिया गया

CREATE TABLE userList
(
    ID INT,
    NAME VARCHAR(20),
    CONSTRAINT us_pk PRIMARY KEY (ID),
    CONSTRAINT us_uq UNIQUE (NAME)  
);

INSERT INTO userList VALUES (1, 'Fluffeh');
INSERT INTO userList VALUES (2, 'John Woo');
INSERT INTO userList VALUES (3, 'hims056');

CREATE TABLE CONVERSATION
(
    ID INT,
    FROM_ID INT,
    TO_ID INT,
    MESSAGE VARCHAR(250),
    DeliveryDate DATE
);

INSERT INTO CONVERSATION VALUES (1, 1, 2, 'hi john', '2012-01-01');
INSERT INTO CONVERSATION VALUES (2, 2, 1, 'hello fluff', '2012-01-02');
INSERT INTO CONVERSATION VALUES (3, 1, 3, 'hey hims', '2012-01-03');
INSERT INTO CONVERSATION VALUES (4, 1, 3, 'please reply', '2012-01-04');
INSERT INTO CONVERSATION VALUES (5, 3, 1, 'how are you?', '2012-01-05');
INSERT INTO CONVERSATION VALUES (6, 3, 2, 'sample message!', '2012-01-05');

सवाल

दो उपयोगकर्ताओं के बीच नवीनतम बातचीत पाएं।

उपाय

SELECT    b.Name SenderName,
          c.Name RecipientName,
          a.Message,
          a.DeliveryDate
FROM      Conversation a
          INNER JOIN userList b
            ON a.From_ID = b.ID
          INNER JOIN userList c
            ON a.To_ID = c.ID
WHERE     (LEAST(a.FROM_ID, a.TO_ID), GREATEST(a.FROM_ID, a.TO_ID), DeliveryDate)
IN
(
    SELECT  LEAST(FROM_ID, TO_ID) minFROM,
            GREATEST(FROM_ID, TO_ID) maxTo,
            MAX(DeliveryDate) maxDate
    FROM    Conversation
    GROUP BY minFROM, maxTo
)

एसक्यूएलफिल्ड डेमो


You can use the concept of multiple queries in the FROM keyword. Let me show you one example:

SELECT DISTINCT e.id,e.name,d.name,lap.lappy LAPTOP_MAKE,c_loc.cnty COUNTY    
FROM  (
          SELECT c.id cnty,l.name
          FROM   county c, location l
          WHERE  c.id=l.county_id AND l.end_Date IS NOT NULL
      ) c_loc, emp e 
      INNER JOIN dept d ON e.deptno =d.id
      LEFT JOIN 
      ( 
         SELECT l.id lappy, c.name cmpy
         FROM   laptop l, company c
         WHERE l.make = c.name
      ) lap ON e.cmpy_id=lap.cmpy

आप जितनी चाहें उतनी टेबल का उपयोग कर सकते हैं। टेबल सबक्वायरीज़ के अंदर भी, जहां भी आवश्यक हो, बाहरी जुड़ने और संघ का उपयोग करें।

टेबल और फ़ील्ड को शामिल करने के लिए यह एक बहुत ही आसान तरीका है।






select