Mysql
 sql >> डेटाबेस >  >> RDS >> Mysql

SQL क्वेरी एकाधिक तालिकाओं से डेटा लौटाती है

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

इस उत्तर में शामिल हैं:

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

डेटाबेस में एकाधिक तालिकाओं से डेटा पुनर्प्राप्त करने के कई तरीके हैं। इस उत्तर में, मैं ANSI-92 जॉइन सिंटैक्स का उपयोग करूँगा। यह कई अन्य ट्यूटोरियल से भिन्न हो सकता है जो पुराने ANSI-89 सिंटैक्स का उपयोग करते हैं (और यदि आप 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)

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

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

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

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 . में एक से अधिक कॉलम में शामिल होना चाह सकते हैं कथन, यहाँ एक उदाहरण है। अगर model तालिका में ब्रांड-विशिष्ट मॉडल थे और इसलिए brand . नामक एक कॉलम भी था जो वापस brands . से जुड़ा हुआ है ID . पर तालिका फ़ील्ड, इसे इस प्रकार किया जा सकता है:

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)

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

ठीक है, तो बॉस वापस आ गया है, और वह फिर से अधिक जानकारी चाहता है। मुझे वही सूची चाहिए, लेकिन उसमें 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 adding जोड़कर उनके बीच खंड, दूसरी क्वेरी के परिणाम पहली क्वेरी के परिणामों में जोड़ दिए जाएंगे।

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

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

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

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

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

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)

और इसके साथ ही, बॉस की खोपड़ी को हटा दें।

अब, इसे कुछ और विस्तार से समझाने के लिए, बाहरी जोड़ left के हो सकते हैं या right प्रकार। बाएँ या दाएँ परिभाषित करते हैं कि कौन-सी तालिका पूरी तरह है शामिल। एक 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 मिलान वाली पंक्ति लौटाएगी क्योंकि यह दोनों मानदंडों को पूरा करता है।

अब, यदि आपका डेटाबेस 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)

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



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. ऑपरेशन '=' के लिए कॉलेशन (utf8_unicode_ci,IMPLICIT) और (utf8_general_ci,IMPLICIT) का अवैध मिश्रण

  2. एक दूरस्थ MySQL डेटाबेस कनेक्शन की स्थापना

  3. क्या MySQL FIND_IN_SET या समकक्ष को इंडेक्स का उपयोग करने के लिए बनाया जा सकता है?

  4. हिब्रू वर्णों के बजाय MySQL डीबी प्रश्न चिह्न ..?

  5. MySQL का अब () +1 दिन