MySQL ON vs KULLANIM?


252

Bir MySQL'de ve JOINarasındaki fark nedir? Anlayabildiğim kadarıyla , sadece daha kullanışlı bir sözdizimi, sütun adları aynı olmadığında biraz daha esneklik sağlar. Ancak, bu fark o kadar küçük ki, onların ortadan kalkacaklarını düşünürsünüz .ONUSING()USING()ONUSING()

Bunun gözle görülenden daha fazlası var mı? Evetse, belirli bir durumda hangisini kullanmalıyım?



usingBirleştirmeler dışında başka bir kullanımı olduğunu unutmayın . Bkz. Stackoverflow.com/a/13750399/632951
Pacerier

Yanıtlar:


400

Çoğunlukla sözdizimsel şekerdir, ancak birkaç fark dikkat çekicidir:

ON , ikisinin daha genelidir. Bir sütun, bir sütun kümesi ve hatta bir koşul tabloları birleştirilebilir. Örneğin:

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

KULLANIM , her iki tabloda da birleştirildikleri adın aynısını içeren bir sütun paylaştığında kullanışlıdır. Bu durumda, kişi şöyle diyebilir:

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

Ek bir güzel muamele, birleştirme sütunlarını tam olarak nitelemeye gerek duymamasıdır:

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

Açıklamak için, yukarıdakileri ON ile yapmak için şunu yazmamız gerekir:

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 ...

Maddedeki film.film_idkalifikasyona dikkat edin SELECT. Bu film_idbir belirsizlik yaratacağı için söylemek yanlış olur:

HATA 1052 (23000): Alan listesindeki 'film_id' sütunu belirsiz

Gelince select *, birleştirme sütunu sonuç kümesinde iki kez ONgörünürken, yalnızca bir kez şu şekilde görünür 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 Sözdizimsel farklılığa güzel cevap. Varsa performans farklılıklarını merak ediyorum. Ben USINGyorumlamak hayal ediyorum ON.
Jason McCreary

9
Aslında, her ikisi de sade eski Teta tarzını yorumlar. Sorgunuzda EXPLAIN EXTENDED öğesini ve ardından UYARILARI GÖSTER komutunu çağırarak görebilirsiniz.
Shlomi Noach

2
Ayrıca bileşik birincil anahtarlar ile katılma faydalı USING(kategori ,field_id yapabilirsiniz ), ayrıca optimize edici bazı durumlarda performansı artırmak için kullandığını duydumUSING
Timo Huovinen

USINGMySQL tanımı mı yoksa standart mı?
PhoneixS


18

Ben ONdaha yararlı bulduk zaman ben burada çip olacağını düşündüm USING. OUTERBirleştirmeler sorgulara eklendiğinde ortaya çıkar.

ONbir sorgunun OUTERbirleştirildiği tablonun sonuç kümesinin birleştirmeyi korurken kısıtlanmasına izin vermenin avantajları OUTER. Bir WHEREcümle belirterek ayarlanan sonuçları kısıtlamaya çalışmak , OUTERbirleştirmeyi etkin bir şekilde bir INNERbirleştirmeye dönüştürecektir .

Bu göreceli bir köşe durumu olabilir. Orada olsa koyarak değer .....

Örneğin:

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
Son derece iyi bir nokta. Tüm avantajlardan using, diğer tahminlerle birleştirilemez: select*from t join t2 using(i) and on 1işe yaramaz.
Pacerier

where hasAirport ;- Ne anlama geliyor ? karşılaştırılacak bir değer yok.
Istiaque Ahmed

Ayrıca ON ile sadece = 'den çok daha fazla karşılaştırma yapabileceğinizi unutmayın. Gibi SELECT * FROM country LEFT JOIN city ON country.countryId=city.countryId AND city.city BETWEEN 'C' AND 'E' tüm ülkeleri listeler ama sadece C veya D ile başlayan şehirler (varsa) listeler. (Artı 'E' olarak adlandırılan kasabalar)
Roemer

Bir kez bile ON bir alt sorgu ile bir JOIN yaptım !!! Hepsi mümkündür ve bazen de oldukça etkilidir.
Roemer

11

Wikipedia hakkında aşağıdaki bilgilere sahiptir USING:

Bununla birlikte, USING yapısı sadece sözdizimsel şekerden daha fazlasıdır, çünkü sonuç kümesi açık yüklemli sürümün sonuç kümesinden farklıdır. Özellikle, KULLANIM listesinde belirtilen sütunlar, birleştirmedeki her tablo için bir kez değil, yalnızca bir kez, niteliksiz bir adla görünür. Yukarıdaki durumda, tek bir Departman Kimliği sütunu olacak ve hiçbir çalışan bulunmayacaktır.

Bahsettiği tablolar:

resim açıklamasını buraya girin

Postgres belgeler de oldukça onları da tanımlar:

ON deyimi en genel birleştirme koşuludur: bir WHERE deyiminde kullanılanla aynı türde bir Boole değeri ifadesi alır. ON ifadesi doğru olarak değerlendirilirse, T1 ve T2'den gelen bir çift satır eşleşir.

USING yan tümcesi, birleştirme işleminin her iki tarafının birleştirme sütun (lar) ı için aynı adı kullandığı özel durumdan yararlanmanızı sağlayan bir stenondur. Paylaşılan sütun adlarının virgülle ayrılmış bir listesini alır ve her biri için bir eşitlik karşılaştırması içeren bir birleştirme koşulu oluşturur. Örneğin, T1 ve T2'yi USING (a, b) ile birleştirmek ON T1.a = T2.a AND T1.b = T2.b'de birleştirme koşulu oluşturur.

Ayrıca, JOIN USING çıktısı gereksiz sütunları bastırır: eşit değerlere sahip olmaları gerektiğinden, eşleşen sütunların her ikisini de yazdırmaya gerek yoktur. JOIN ON, T1'den tüm sütunları ve ardından T2'den tüm sütunları üretirken, JOIN USING, listelenen sütun çiftlerinin her biri için (listelenen sırada) bir çıkış sütunu, ardından T1'den kalan sütunları ve ardından T2'den kalan sütunları üretir. .


1

PhpMyAdmin'de bunu deneyenler için, sadece bir kelime:

phpMyAdmin ile ilgili birkaç sorun var gibi görünüyor USING. Kayıt için bu Linux Mint üzerinde çalışan phpMyAdmin, sürüm: "4.5.4.1deb2ubuntu2", Veritabanı sunucusu: "10.2.14-MariaDB-10.2.14 + maria ~ xenial - mariadb.org ikili dağıtım".

Ben ve hem phpMyAdmin ve Terminal (komut satırı) SELECTkullanarak komutları çalıştırmak var JOINve USINGphpMyAdmin olanlar bazı şaşırtıcı yanıtlar üretmek:

1) LIMITsondaki bir madde yok sayılıyor gibi görünüyor.
2) sayfanın üst kısmında, sonuçlarla birlikte rapor edilen varsayılan satır sayısı bazen yanlış olabilir: örneğin 4 döndürülür, ancak üstte "0 - 24 arasındaki satırlar gösteriliyor (toplam 2503, Sorgu 0.0018 saniye sürdü). "

Mysql'de normal olarak oturum açmak ve aynı sorguları çalıştırmak bu hataları üretmez. PhpMyAdmin kullanarak aynı sorguyu çalıştırırken bu hatalar oluşmaz JOIN ... ON .... Muhtemelen bir phpMyAdmin hatası.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.