Cross Join için kullanım alanları nelerdir?


105

Çapraz birleştirme, iki kümenin demetleri üzerinde kartezyen bir ürün gerçekleştirir.

SELECT *
FROM Table1
CROSS JOIN Table2

Hangi koşullar böyle bir SQL işlemini özellikle yararlı kılar?


36
Bu sorunun kapatılmış olması gerçekten üzücü. Bence Topluluk Wiki olarak işaretlenebilir, ancak yapıcı olmadığını söylemek haksızlık olur.
Wayne Koorts

1
Katılıyorum. Bu, sahip olduğum tam soruyu cevapladı.
Hades

10
Daha yeni bir geliştiricinin, kullandığı yazılımın belirli işlevlerinin sonuçlarını anlamakta güçlük çektiği zamanlar vardır. Bunun gibi sorular, özellikle yeni geliştiriciler için yararlıdır, çünkü aşağıdaki tartışma, genç geliştiricinin asla düşünmediği birçok olasılığı aydınlatır. Sorunun formatı en iyi ihtimalle temeldir, ancak niyetin "bu neden var?" Diye sorması nedeniyle dürüst görünmektedir. Wayne Koorts'a katılıyorum, casperOne'ın bunu kapatmayı seçmesi ve bunu "yapıcı değil" olarak adlandırması utanç verici. "Yapıcı olmayan" kısmı beni özellikle rahatsız ediyor.
Kaorie

Yanıtlar:


93

Belirli bir giyim eşyası için beden ve renk bilgileri gibi, tamamen doldurmak istediğiniz bir "ızgaranız" varsa:

select 
    size,
    color
from
    sizes CROSS JOIN colors

Belki de gün içinde her dakika için bir satır içeren bir tablo istiyorsunuz ve bunu her dakika bir prosedürün yürütüldüğünü doğrulamak için kullanmak istiyorsunuz, böylece üç tabloyu geçebilirsiniz:

select
    hour,
    minute
from
    hours CROSS JOIN minutes

Veya yıl içinde her ay uygulamak istediğiniz bir dizi standart rapor spesifikasyonunuz vardır:

select
    specId,
    month
from
    reports CROSS JOIN months

Bunları görüş olarak sürdürmenin sorunu, çoğu durumda, özellikle giysilerle ilgili olarak tam bir ürün istememenizdir. MINUSTaşımadığınız belirli kombinasyonları kaldırmak için sorguya mantık ekleyebilirsiniz , ancak bir tabloyu başka bir şekilde doldurmayı ve Kartezyen ürünü kullanmamayı daha kolay bulabilirsiniz.

Ayrıca, belki de düşündüğünüzden birkaç satır daha fazla olan tablolarda çapraz birleştirmeyi deneyebilirsiniz veya belki de WHEREcümleniz kısmen veya tamamen eksiktir. Bu durumda, DBA'nız ihmal konusunda sizi derhal bilgilendirecektir. Genellikle mutlu olmayacaktır.


5
... Bu durumda, DBA'nız ihmal konusunda sizi derhal bilgilendirecektir. Genellikle mutlu olmayacaktır. ... haha, çok doğru!
RSW

2
@Dave: İkinci örnek sadece bir saat CROSS JOIN dakikası olmayacak mı?
Rakesh

@Rakesh, iyi yakaladım, yazdığımdan başka bir şey düşünüyordum. Sabit.
Dave DuPlantis

1
Size 2 set id (belki csv formatında) verilirse, bir set çalışan kimliklerini ve diğeri görev kimliklerini içerecek şekilde çapraz birleştirme çok pratik olduğunu hayal edebiliyorum. Fikir, EmployeeTask için bir M2M tablonuzun olmasıdır. Csv'yi tablo değişkenlerine (veya başka bir şeye) dönüştürdüğünüz için, verilen her görevi her çalışana atamak için çapraz birleştirmeyi kullanabilirsiniz.
SynBiotik


14

Çoğu veritabanı sorgusu için genellikle tam bir Kartezyen ürün istemezsiniz. İlişkisel veritabanlarının tüm gücü, db'den gereksiz satırları çekmekten kaçınmanıza izin vermek için ilginizi çekebilecek her türlü kısıtlamayı uygulayabilmenizdir.

Sanırım bunu isteyebileceğiniz bir uydurma örnek, bir çalışan masanız ve yapılması gereken bir iş masanız varsa ve bir çalışanın tek bir işe olası tüm atamalarını görmek istiyorsanız.


11

Tamam, bu muhtemelen soruyu cevaplamaz, ama doğruysa (ve bundan emin değilim bile) eğlenceli bir tarih.

Oracle'ın ilk günlerinde, geliştiricilerden biri bir tablodaki her satırı çoğaltması gerektiğini fark etti (örneğin, bir olaylar tablosu olabilir ve bunu "başlangıç ​​olayı" ve "bitiş etkinliği" ni ayrı ayrı değiştirmesi gerekiyordu. girdileri). Sadece iki sıralı bir masasına sahip olsaydı, sadece ilk tablodaki sütunları seçerek bir çapraz birleştirme yapabileceğini ve tam olarak ihtiyacı olanı elde edebileceğini fark etti. Böylece doğal olarak yeterince "DUAL" adını verdiği basit bir masa yarattı.

Daha sonra, eylemin masayla hiçbir ilgisi olmasa bile, yalnızca bir tablodan seçim yoluyla yapılabilecek bir şey yapması gerekiyor (belki saatini unutmuş ve saati SEÇİM SYSDATE FROM ile okumak istemiştir .. .) DUAL masasının hala ortalıkta olduğunu fark etti ve onu kullandı. Bir süre sonra, zamanın iki kez yazdırıldığını görmekten yoruldu, bu yüzden sonunda satırlardan birini sildi.

Oracle'daki diğerleri masasını kullanmaya başladı ve sonunda, standart Oracle kurulumuna dahil edilmesine karar verildi.

Bu da tek anlamı bir satıra sahip olması olan bir tablonun neden "iki" anlamına gelen bir ada sahip olduğunu açıklıyor.


8

Anahtar "bana tüm olası kombinasyonları göster" dir. Bunları diğer hesaplanan alanlarla birlikte kullandım ve daha sonra bunları sıraladım / filtreledim.

Örneğin, bir arbitraj (ticaret) uygulaması oluşturduğunuzu varsayalım. Ürünleri bir fiyata sunan satıcılarınız ve bir ücret karşılığında ürün isteyen alıcılarınız var. Ürün anahtarında bir çapraz birleştirme yaparsınız (potansiyel alıcıları ve satıcıları eşleştirmek için), maliyet ve fiyat arasındaki farkı hesaplayın ve ardından azalan sıralayın. size (aracıya) yürütmek için en karlı işlemleri vermek için. Elbette neredeyse her zaman başka sınırlayıcı filtre kriterlerine sahip olacaksınız.


Ah! Bu açıklama bana çok mantıklı geliyor. Bu durumda, bir INNER JOIN bir anlam ifade etmez çünkü bir ürün kimliği ile bir satıcı arasında bir ilişki yoktur, çünkü birden fazla satıcı aynı ürünü satabilir.
moonman239

3

0-9 rakamları için on satır içeren rakam tablosu gibi bir şey alır. Sonuçların uygun şekilde numaralandırıldığı, ihtiyacınız olan sayıda satıra sahip bir sonuç elde etmek için bu tabloda çapraz birleştirmeyi birkaç kez kullanabilirsiniz. Bunun birçok kullanımı vardır. Örneğin, belirli bir yıldaki her gün için bir set elde etmek için bunu bir datadd () işleviyle birleştirebilirsiniz.



1

Belirli bir öğe ve tarih kombinasyonu (fiyatlar, kullanılabilirlik, vb.) Üzerinden yayınlamak istediğiniz bir dizi sorunuz olduğunu düşünün. Öğeleri ve tarihleri ​​ayrı geçici tablolara yükleyebilir ve sorgularınızın tablolarla çapraz birleşmesini sağlayabilirsiniz. Bu, IN cümlesindeki öğeleri ve tarihleri ​​sıralamanın alternatifinden daha uygun olabilir, özellikle bazı veritabanları bir IN cümlesindeki öğelerin sayısını sınırladığından.


1

CROSS JOIN'i aşağıdakiler için kullanabilirsiniz : - test amaçlı veri oluşturmak - tüm özellikleri birleştirmek - örneğin kan gruplarının (A, B, ..) Rh - / +, vb. ile tüm olası kombinasyonlarına ihtiyacınız var - ayar yapmak amaçlarınız için;) - Bu alanda uzman değilim;)

CREATE TABLE "HR"."BL_GRP_01" 
("GR_1" VARCHAR2(5 BYTE));
REM INSERTING into BL_GRP_01
SET DEFINE OFF;
Insert into BL_GRP_02 (GR_1) values ('A');
Insert into BL_GRP_02 (GR_1) values ('B');
Insert into BL_GRP_02 (GR_1) values ('O');
Insert into BL_GRP_01 (GR_1) values (NULL);

CREATE TABLE "HR"."BL_GRP_02" 
("GR_1" VARCHAR2(5 BYTE));

REM INSERTING into BL_GRP_02
SET DEFINE OFF;
Insert into BL_GRP_02 (GR_1) values ('A');
Insert into BL_GRP_02 (GR_1) values ('B');
Insert into BL_GRP_02 (GR_1) values ('O');
Insert into BL_GRP_02 (GR_1) values (NULL);

CREATE TABLE "HR"."RH_VAL_01" 
("RH_VAL" VARCHAR2(5 BYTE));
REM INSERTING into RH_VAL_01
SET DEFINE OFF;
Insert into RH_VAL_01 (RH_VAL) values ('+');
Insert into RH_VAL_01 (RH_VAL) values ('-');
Insert into RH_VAL_01 (RH_VAL) values (NULL);

select distinct  a.GR_1 || b.GR_1 || c.RH_VAL as BL_GRP
from BL_GRP_01 a, BL_GRP_02 b, RH_VAL_01 c
GROUP BY a.GR_1, b.GR_1, c.RH_VAL;
  • ortak bir kimlik olmadan 2 tablo için bir birleştirme oluşturun ve ardından mümkün olan en yüksek kombinasyonu bulmak için max () vb. kullanarak gruplayın.
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.