MySQL पर उपयोग बनाम?


252

एक MySQL में JOIN, के बीच अंतर क्या है ONऔर USING()? जहां तक ​​मैं बता सकता हूं, USING()बस अधिक सुविधाजनक वाक्यविन्यास है, जबकि ONकॉलम नाम समान नहीं होने पर थोड़ा अधिक लचीलापन देता है। हालाँकि, यह अंतर इतना मामूली है, आपको लगता है कि वे अभी दूर करेंगे USING()

क्या आंख से मिलने से ज्यादा यह होता है? यदि हाँ, तो मुझे दी गई स्थिति में किसका उपयोग करना चाहिए?


1
वहाँ भी प्राकृतिक
जॉय है

ध्यान दें कि usingजुड़ने के अलावा एक और उपयोग है। देखें stackoverflow.com/a/13750399/632951
Pacerier

जवाबों:


400

यह ज्यादातर सिंटैक्टिक शुगर है, लेकिन कुछ अंतर उल्लेखनीय हैं:

ON दोनों का अधिक सामान्य है। कोई एक स्तंभ, एक स्तंभ और यहां तक ​​कि एक शर्त पर तालिकाओं में शामिल हो सकता है। उदाहरण के लिए:

SELECT * FROM world.City JOIN world.Country ON (City.CountryCode = Country.Code) WHERE ...

उपयोग करना तब उपयोगी होता है जब दोनों तालिकाओं में ठीक उसी नाम का एक कॉलम साझा किया जाता है जिस पर वे शामिल होते हैं। इस मामले में, कोई कह सकता है:

SELECT ... FROM film JOIN film_actor USING (film_id) WHERE ...

एक अतिरिक्त अच्छा इलाज यह है कि किसी को ज्वाइनिंग कॉलम को पूरी तरह से क्वालीफाई करने की आवश्यकता नहीं है:

SELECT film.title, film_id -- film_id is not prefixed
FROM film
JOIN film_actor USING (film_id)
WHERE ...

उदाहरण के लिए, उपरोक्त को ON के साथ करने के लिए , हमें लिखना होगा:

SELECT film.title, film.film_id -- film.film_id is required here
FROM film
JOIN film_actor ON (film.film_id = film_actor.film_id)
WHERE ...

क्लॉज film.film_idमें योग्यता पर ध्यान दें SELECT। यह सिर्फ यह कहना अमान्य film_idहोगा कि इससे अस्पष्टता पैदा होगी:

त्रुटि 1052 (23000): क्षेत्र सूची में कॉलम 'film_id' अस्पष्ट है

जैसा कि select *, जुड़ने वाला कॉलम दो बार सेट किए गए परिणाम में दिखाई देता है, ONजबकि यह केवल एक बार साथ दिखाई देता है USING:

mysql> create table t(i int);insert t select 1;create table t2 select*from t;
Query OK, 0 rows affected (0.11 sec)

Query OK, 1 row affected (0.00 sec)
Records: 1  Duplicates: 0  Warnings: 0

Query OK, 1 row affected (0.19 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> select*from t join t2 on t.i=t2.i;
+------+------+
| i    | i    |
+------+------+
|    1 |    1 |
+------+------+
1 row in set (0.00 sec)

mysql> select*from t join t2 using(i);
+------+
| i    |
+------+
|    1 |
+------+
1 row in set (0.00 sec)

mysql>

2
+1 वाक्यविन्यास अंतर पर अच्छा जवाब। यदि कोई हो, तो मैं प्रदर्शन मतभेदों को लेकर उत्सुक हूं। मैं कल्पना करता हूं कि मैं इसकी USINGव्याख्या करता हूं ON
जेसन मैकक्रेरी

9
दरअसल, दोनों सादे पुराने थेटा-शैली की व्याख्या करते हैं। आप यह देख सकते हैं कि अपनी क्वेरी पर EXPLAIN EXTENDED को आमंत्रित करने के बाद, SHOW WARNINGS द्वारा।
श्लोमी नोआच

2
आप USING(श्रेणी ,field_id भी कर सकते हैं, )जो समग्र प्राथमिक कुंजियों से जुड़ने पर उपयोगी होता है, मैंने यह भी सुना कि अनुकूलक USINGकुछ मामलों में प्रदर्शन को बेहतर बनाने के लिए उपयोग करता है
टिमो हुओवेंन

है USINGएक MySQL परिभाषा या यह मानक है?
फोनिक्स

5
@PhoneixS उस में है ANSI SQL 92 मानक
Shlomi Noach

18

सोचा था कि जब मैं इससे ONअधिक उपयोगी पाया जाएगा, तो मैं यहां चिप लगाऊंगा USING। यह तब OUTERहोता है जब जॉइन को प्रश्नों में पेश किया जाता है।

ONतालिका के परिणामों के सेट की अनुमति देने से लाभ, जो एक क्वेरी में OUTERशामिल होने के दौरान प्रतिबंधित होने पर OUTERशामिल हो रहा है। WHEREप्रभावी ढंग से एक क्लॉज को निर्दिष्ट करने के माध्यम से सेट किए गए परिणामों को प्रतिबंधित करने का प्रयास करते हुए , OUTERज्वाइन को ज्वाइन में बदलें INNER

दी यह एक रिश्तेदार कोने का मामला हो सकता है। हालांकि वहाँ बाहर रखने लायक .....

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

CREATE TABLE country (
   countryId int(10) unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
   country varchar(50) not null,
  UNIQUE KEY countryUIdx1 (country)
) ENGINE=InnoDB;

insert into country(country) values ("France");
insert into country(country) values ("China");
insert into country(country) values ("USA");
insert into country(country) values ("Italy");
insert into country(country) values ("UK");
insert into country(country) values ("Monaco");


CREATE TABLE city (
  cityId int(10) unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT,
  countryId int(10) unsigned not null,
  city varchar(50) not null,
  hasAirport boolean not null default true,
  UNIQUE KEY cityUIdx1 (countryId,city),
  CONSTRAINT city_country_fk1 FOREIGN KEY (countryId) REFERENCES country (countryId)
) ENGINE=InnoDB;


insert into city (countryId,city,hasAirport) values (1,"Paris",true);
insert into city (countryId,city,hasAirport) values (2,"Bejing",true);
insert into city (countryId,city,hasAirport) values (3,"New York",true);
insert into city (countryId,city,hasAirport) values (4,"Napoli",true);
insert into city (countryId,city,hasAirport) values (5,"Manchester",true);
insert into city (countryId,city,hasAirport) values (5,"Birmingham",false);
insert into city (countryId,city,hasAirport) values (3,"Cincinatti",false);
insert into city (countryId,city,hasAirport) values (6,"Monaco",false);

-- Gah. Left outer join is now effectively an inner join 
-- because of the where predicate
select *
from country left join city using (countryId)
where hasAirport
; 

-- Hooray! I can see Monaco again thanks to 
-- moving my predicate into the ON
select *
from country co left join city ci on (co.countryId=ci.countryId and ci.hasAirport)
; 

4
बहुत अच्छी बात है। सभी लाभों में से using, यह अन्य विधेय के साथ जोड़ा नहीं जा सकता: select*from t join t2 using(i) and on 1काम नहीं करेगा।
पेसरियर

where hasAirport ;- इसका क्या मतलब है ? तुलना करने के लिए कोई मूल्य नहीं है।
इस्तियाक अहमद

यह भी ध्यान दें कि आप केवल = के बजाय ON के साथ अधिक तुलना कर सकते हैं। जैसे SELECT * FROM country LEFT JOIN city ON country.countryId=city.countryId AND city.city BETWEEN 'C' AND 'E' सभी देशों को सूचीबद्ध करेगा लेकिन सिर्फ C या D (यदि कोई हो) से शुरू होने वाले शहर। (प्लस शहरों को 'ई' कहा जाता है)
रोमेर

मैं भी एक बार में एक उप के साथ एक JOIN किया !!! यह सब संभव है और कभी-कभी अत्यधिक प्रभावी होता है।
रोमेर

11

विकिपीडिया के बारे में निम्नलिखित जानकारी है USING:

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

टेबल्स जो इसके बारे में बात कर रहे थे:

यहां छवि विवरण दर्ज करें

Postgres प्रलेखन भी उन्हें बहुत अच्छी तरह से परिभाषित करता है:

ऑन क्लॉज सबसे सामान्य प्रकार की जॉइन कंडीशन है: यह उसी तरह की बूलियन वैल्यू एक्सप्रेशन लेती है जैसे कि WHERE क्लॉज में इस्तेमाल की जाती है। T1 और T2 से पंक्तियों की एक जोड़ी मेल खाती है यदि ON अभिव्यक्ति सत्य का मूल्यांकन करती है।

USING क्लॉज एक शॉर्टहैंड है जो आपको उस विशिष्ट स्थिति का लाभ उठाने की अनुमति देता है, जिसमें शामिल होने वाले दोनों पक्ष जॉइनिंग कॉलम (एस) के लिए एक ही नाम का उपयोग करते हैं। यह साझा किए गए स्तंभ नामों की अल्पविराम से अलग की गई सूची में शामिल हो जाता है और एक सम्मिलित स्थिति बनाता है जिसमें प्रत्येक के लिए एक समानता की तुलना शामिल होती है। उदाहरण के लिए, T1 और T2 को USING (a, b) के साथ मिलाने पर T1.a = T2.a और T1.b = T2.b.

इसके अलावा, JOIN USING का उत्पादन निरर्थक कॉलम को दबा देता है: दोनों मिलान किए गए कॉलम को प्रिंट करने की कोई आवश्यकता नहीं है, क्योंकि उनके पास समान मान होना चाहिए। जबकि JOIN T2 से सभी स्तंभों के बाद T1 से सभी स्तंभों का उत्पादन करता है, JOIN USING प्रत्येक सूचीबद्ध कॉलम जोड़े (सूचीबद्ध क्रम में) में से प्रत्येक के लिए एक आउटपुट कॉलम का उत्पादन करता है, इसके बाद T1 से कोई भी शेष कॉलम, उसके बाद T2 के किसी भी शेष कॉलम का निर्माण करता है। ।


1

PhpMyAdmin में इसके साथ प्रयोग करने वालों के लिए, केवल एक शब्द:

phpMyAdmin के साथ कुछ समस्याएँ प्रतीत होती हैं USING। रिकॉर्ड के लिए यह लिनक्स मिंट पर phpMyAdmin रन है, संस्करण: "4.5.4.1deb2ubuntu2", डेटाबेस सर्वर: "10.2.14-MariaDB-10.2.14 + मारिया ~ xenial - mariialb.org द्विआधारी वितरण"।

मैं चलाने SELECTका उपयोग कर आदेशों JOINऔर USINGदोनों phpMyAdmin में और टर्मिनल (कमांड लाइन) में, और phpMyAdmin में लोगों को कुछ चौंकाने प्रतिक्रियाओं का उत्पादन:

1) LIMITअंत में एक खंड नजरअंदाज कर दिया जाता है।
2) परिणामों के साथ पृष्ठ के शीर्ष पर बताई गई पंक्तियों की संख्या कभी-कभी गलत होती है: उदाहरण के लिए 4 वापस कर दी जाती हैं, लेकिन शीर्ष पर यह कहा गया है "पंक्तियों को दिखाना 0 - 24 (2503 कुल, क्वेरी ने 0.0018 सेकंड लिया।) "

सामान्य रूप से mysql पर लॉग इन करना और समान क्वेरी को चलाना इन त्रुटियों को उत्पन्न नहीं करता है। न ही इन त्रुटियों का उपयोग करते हुए phpMyAdmin में समान क्वेरी चलाते हैं JOIN ... ON ...। संभवतः एक phpMyAdmin बग।

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