Apa kegunaan untuk Cross Join?


105

Gabungan silang melakukan produk kartesius pada tupel dari dua set.

SELECT *
FROM Table1
CROSS JOIN Table2

Keadaan apa yang membuat operasi SQL seperti itu sangat berguna?


36
Sangat menyedihkan bahwa pertanyaan ini telah ditutup. Saya pikir itu bisa ditandai sebagai Wiki Komunitas, tetapi mengatakan itu tidak membangun adalah tidak adil.
Wayne Koorts

1
Saya setuju. Ini menjawab pertanyaan yang saya miliki.
Hades

10
Ada kalanya pengembang yang lebih baru kesulitan memahami implikasi fungsi tertentu dari perangkat lunak yang mereka gunakan. Pertanyaan seperti ini sangat membantu bagi developer yang lebih baru, terutama karena diskusi berikut menjelaskan banyak kemungkinan yang tidak pernah dipertimbangkan oleh developer junior. Format pertanyaannya paling dasar, tetapi maksudnya tampaknya jujur ​​karena bertanya "mengapa ini ada?" Saya setuju dengan Wayne Koorts, sayang sekali casperOne memilih untuk menutup ini dan menyebutnya "tidak konstruktif". Bagian "tidak membangun" membuat saya kesal.
Kaorie

Jawaban:


93

Jika Anda memiliki "kisi" yang ingin Anda isi seluruhnya, seperti informasi ukuran dan warna untuk artikel pakaian tertentu:

select 
    size,
    color
from
    sizes CROSS JOIN colors

Mungkin Anda menginginkan tabel yang berisi baris untuk setiap menit dalam sehari, dan Anda ingin menggunakannya untuk memverifikasi bahwa prosedur telah dijalankan setiap menit, jadi Anda mungkin melintasi tiga tabel:

select
    hour,
    minute
from
    hours CROSS JOIN minutes

Atau Anda memiliki sekumpulan spesifikasi laporan standar yang ingin Anda terapkan setiap bulan dalam setahun:

select
    specId,
    month
from
    reports CROSS JOIN months

Masalah dengan mempertahankan ini sebagai pandangan adalah bahwa dalam banyak kasus, Anda tidak menginginkan produk yang lengkap, terutama yang berkaitan dengan pakaian. Anda dapat menambahkan MINUSlogika ke kueri untuk menghapus kombinasi tertentu yang tidak Anda bawa, tetapi Anda mungkin merasa lebih mudah untuk mengisi tabel dengan cara lain dan tidak menggunakan produk Cartesian.

Selain itu, Anda mungkin akan mencoba gabungan silang pada tabel yang mungkin memiliki beberapa baris lebih banyak dari yang Anda kira, atau mungkin WHEREklausa Anda sebagian atau seluruhnya hilang. Dalam hal ini, DBA Anda akan segera memberi tahu Anda tentang kelalaian tersebut. Biasanya dia tidak akan bahagia.


5
... Dalam hal ini, DBA Anda akan segera memberi tahu Anda tentang kelalaian tersebut. Biasanya dia tidak akan bahagia. ... haha, benar sekali!
RSW

2
@ Dave: Bukankah contoh kedua akan menjadi hanya jam CROSS JOIN menit?
Rakesh

@Rakesh, tangkapan bagus, saya sedang memikirkan sesuatu selain apa yang saya ketik. Tetap.
Dave DuPlantis

1
Saya dapat membayangkan cross join menjadi sangat praktis jika Anda diberi 2 set id (mungkin dalam format csv), satu set akan berisi id karyawan dan yang lainnya akan berisi id tugas. Idenya adalah Anda memiliki tabel M2M untuk EmployeeTask. Anda dapat menggunakan gabungan silang untuk menetapkan setiap tugas yang diberikan kepada setiap karyawan tertentu, asalkan Anda mengubah csv menjadi variabel tabel (atau sesuatu).
SynBiotik


14

Anda biasanya tidak menginginkan produk Cartesian lengkap untuk sebagian besar kueri database. Seluruh kekuatan database relasional adalah Anda dapat menerapkan batasan apa pun yang mungkin Anda minati untuk memungkinkan Anda menghindari penarikan baris yang tidak perlu dari db.

Saya kira satu contoh buatan yang mungkin Anda inginkan adalah jika Anda memiliki tabel karyawan dan tabel pekerjaan yang perlu dilakukan dan ingin melihat semua kemungkinan penugasan dari satu karyawan untuk satu pekerjaan.


11

Oke, ini mungkin tidak akan menjawab pertanyaannya, tetapi, jika itu benar (dan saya bahkan tidak yakin tentang itu) itu sedikit sejarah yang menyenangkan.

Pada masa-masa awal Oracle, salah satu pengembang menyadari bahwa dia perlu menduplikasi setiap baris dalam sebuah tabel (misalnya, mungkin saja itu adalah tabel kejadian dan dia perlu mengubahnya secara terpisah "mulai acara" dan "acara akhir" entri). Dia menyadari bahwa jika dia memiliki tabel dengan hanya dua baris, dia dapat melakukan penggabungan silang, hanya memilih kolom di tabel pertama, dan mendapatkan apa yang dia butuhkan. Jadi dia membuat meja sederhana, yang secara alami dia sebut "DUAL".

Nanti, dia perlu melakukan sesuatu yang hanya bisa dilakukan melalui pemilihan dari tabel, meskipun aksinya sendiri tidak ada hubungannya dengan tabel, (mungkin dia lupa jam tangannya dan ingin membaca waktu melalui SELECT SYSDATE FROM .. .) Dia menyadari bahwa dia masih memiliki meja DUAL tergeletak di sekitar, dan menggunakannya. Setelah beberapa saat, dia lelah melihat waktu dicetak dua kali, jadi dia akhirnya menghapus salah satu baris.

Orang lain di Oracle mulai menggunakan mejanya, dan akhirnya, diputuskan untuk memasukkannya ke dalam instalasi Oracle standar.

Yang menjelaskan mengapa tabel yang hanya memiliki satu baris memiliki nama yang berarti "dua".


8

Kuncinya adalah "tunjukkan semua kemungkinan kombinasi". Saya telah menggunakan ini bersama dengan kolom kalkulasi lain dan kemudian mengurutkan / memfilternya.

Misalnya, Anda sedang membangun aplikasi arbitrase (perdagangan). Anda memiliki penjual yang menawarkan produk dengan harga tertentu dan pembeli meminta produk dengan harga tertentu. Anda melakukan cross join pada product key (untuk mencocokkan calon pembeli dan penjual), menghitung spread antara cost dan price, lalu mengurutkan desc. dalam hal ini untuk memberi Anda (perantara) perdagangan paling menguntungkan untuk dieksekusi. Hampir selalu Anda akan memiliki kriteria filter pembatas lainnya tentunya.


Ah! Penjelasan ini paling masuk akal bagi saya. Dalam hal ini, INNER JOIN tidak masuk akal karena tidak ada hubungan antara ID produk dan penjual, karena beberapa penjual dapat menjual produk yang sama.
moonman239

3

Mengambil sesuatu seperti tabel digit, yang memiliki sepuluh baris untuk digit 0-9. Anda dapat menggunakan gabungan silang pada tabel itu beberapa kali untuk mendapatkan hasil yang memiliki berapa banyak baris yang Anda butuhkan, dengan hasil yang dinomori dengan tepat. Ini memiliki sejumlah kegunaan. Misalnya, Anda bisa menggabungkannya dengan fungsi datadd () untuk mendapatkan satu set untuk setiap hari di tahun tertentu.



1

Bayangkan Anda memiliki serangkaian pertanyaan yang ingin Anda keluarkan atas kombinasi item dan tanggal tertentu (harga, ketersediaan, dll ..). Anda dapat memuat item dan tanggal ke tabel temp yang terpisah dan membuat kueri Anda bergabung dengan tabel. Ini mungkin lebih mudah daripada alternatif untuk menghitung item dan tanggal dalam klausa IN, terutama karena beberapa database membatasi jumlah elemen dalam klausa IN.


1

Anda dapat menggunakannya CROSS JOIN untuk: - menghasilkan data untuk tujuan pengujian - menggabungkan semua properti - Anda memerlukan semua kemungkinan kombinasi misalnya golongan darah (A, B, ..) dengan Rh - / +, dll ... - menyetelnya untuk tujuan Anda;) - Saya tidak ahli di bidang ini;)

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;
  • buat gabungan untuk 2 tabel tanpa id umum dan kemudian kelompokkan menggunakan max (), dll .. untuk menemukan kombinasi setinggi mungkin
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.