การใช้งาน Cross Join คืออะไร?


107

การรวมแบบไขว้จะทำผลิตภัณฑ์คาร์ทีเซียนบนสิ่งที่สองของทั้งสองเซ็ต

SELECT *
FROM Table1
CROSS JOIN Table2

สถานการณ์ใดที่ทำให้การดำเนินการ SQL ดังกล่าวมีประโยชน์อย่างยิ่ง?


37
เป็นเรื่องน่าเศร้าจริงๆที่คำถามนี้ถูกปิดลง ฉันคิดว่ามันอาจถูกทำเครื่องหมาย Community Wiki แต่การบอกว่ามันไม่สร้างสรรค์นั้นไม่ยุติธรรม
Wayne Koorts

1
ฉันเห็นด้วย. สิ่งนี้ตอบคำถามที่ฉันมี
Hades

10
มีหลายครั้งที่นักพัฒนารุ่นใหม่มีปัญหาในการทำความเข้าใจผลกระทบของฟังก์ชันบางอย่างของซอฟต์แวร์ที่พวกเขาใช้ คำถามเช่นนี้เป็นประโยชน์เฉพาะสำหรับนักพัฒนารุ่นใหม่โดยเฉพาะอย่างยิ่งเนื่องจากการสนทนาที่ตามมาทำให้เกิดความเป็นไปได้มากมายที่นักพัฒนารุ่นเยาว์ไม่เคยพิจารณา รูปแบบของคำถามเป็นพื้นฐานที่ดีที่สุด แต่ดูเหมือนว่าเจตนาจะตรงไปตรงมาเมื่อถามว่า "ทำไมถึงมีอยู่จริง" ฉันเห็นด้วยกับ Wayne Koorts เป็นเรื่องน่าเสียดายที่ casperOne เลือกที่จะปิดสิ่งนี้และเรียกมันว่า "ไม่สร้างสรรค์" ส่วนที่ "ไม่สร้างสรรค์" โดยเฉพาะทำให้ฉันรำคาญ
Kaorie

คำตอบ:


94

หากคุณมี "เส้นตาราง" ที่ต้องการเติมข้อมูลให้ครบถ้วนเช่นข้อมูลขนาดและสีสำหรับเสื้อผ้าชิ้นใดชิ้นหนึ่ง:

select 
    size,
    color
from
    sizes CROSS JOIN colors

บางทีคุณอาจต้องการตารางที่มีแถวสำหรับทุกนาทีในวันและคุณต้องการใช้เพื่อตรวจสอบว่าขั้นตอนดำเนินการในแต่ละนาทีดังนั้นคุณอาจข้ามสามตาราง:

select
    hour,
    minute
from
    hours CROSS JOIN minutes

หรือคุณมีชุดข้อกำหนดของรายงานมาตรฐานที่คุณต้องการนำไปใช้ทุกเดือนในปี:

select
    specId,
    month
from
    reports CROSS JOIN months

ปัญหาในการรักษาสิ่งเหล่านี้เป็นมุมมองคือในกรณีส่วนใหญ่คุณไม่ต้องการผลิตภัณฑ์ที่สมบูรณ์โดยเฉพาะอย่างยิ่งในส่วนที่เกี่ยวกับเสื้อผ้า คุณสามารถเพิ่มMINUSตรรกะในแบบสอบถามเพื่อลบชุดค่าผสมบางอย่างที่คุณไม่ได้พกพาได้ แต่คุณอาจพบว่าง่ายกว่าในการเติมข้อมูลในตารางด้วยวิธีอื่นและไม่ใช้ผลิตภัณฑ์คาร์ทีเซียน

นอกจากนี้คุณอาจลองใช้ cross join บนโต๊ะที่อาจมีแถวมากกว่าที่คุณคิดไว้สักสองสามแถวหรือบางทีWHEREประโยคของคุณขาดหายไปบางส่วนหรือทั้งหมด ในกรณีนั้น DBA ของคุณจะแจ้งให้คุณทราบทันทีถึงการละเว้น โดยปกติเขาหรือเธอจะไม่มีความสุข


5
... ในกรณีนั้น DBA ของคุณจะแจ้งให้คุณทราบทันทีถึงการละเว้น โดยปกติเขาหรือเธอจะไม่มีความสุข ... ฮาจริง!
RSW

2
@ เดฟ: ตัวอย่างที่สองเคยเป็นเพียงชั่วโมงข้ามเข้าร่วมนาทีหรือไม่?
Rakesh

@Rakesh จับดีฉันกำลังคิดอย่างอื่นที่ไม่ใช่สิ่งที่ฉันกำลังพิมพ์ แก้ไขแล้ว.
Dave DuPlantis

1
ฉันนึกภาพออกว่าการเข้าร่วมแบบไขว้เป็นประโยชน์อย่างมากหากคุณได้รับ id 2 ชุด (อาจอยู่ในรูปแบบ csv) ชุดหนึ่งจะมีรหัสพนักงานและอีกชุดหนึ่งจะมีรหัสงาน แนวคิดก็คือคุณมีตาราง M2M สำหรับ EmployeeTask คุณสามารถใช้ cross join เพื่อมอบหมายงานที่กำหนดให้กับพนักงานทุกคนโดยให้คุณเปลี่ยน csv เป็นตัวแปรตาราง (หรือบางอย่าง)
SynBiotik

21

สร้างข้อมูลสำหรับการทดสอบ


ฉันไม่เคยคิดเลยว่าจะเห็น "คำตอบ" 4 คำได้รับคะแนนโหวต 9 คะแนน
mickmackusa

14

โดยทั่วไปคุณจะไม่ต้องการผลิตภัณฑ์คาร์ทีเซียนแบบเต็มสำหรับการสืบค้นฐานข้อมูลส่วนใหญ่ พลังทั้งหมดของฐานข้อมูลเชิงสัมพันธ์คือคุณสามารถใช้ข้อ จำกัด ใด ๆ ที่คุณอาจสนใจเพื่อให้คุณหลีกเลี่ยงการดึงแถวที่ไม่จำเป็นออกจากฐานข้อมูล

ฉันคิดว่าตัวอย่างที่สร้างขึ้นอย่างหนึ่งที่คุณอาจต้องการนั่นคือถ้าคุณมีโต๊ะพนักงานและตารางงานที่ต้องทำและต้องการดูการมอบหมายงานทั้งหมดที่เป็นไปได้ของพนักงานหนึ่งคนต่อหนึ่งงาน


11

โอเคนี่อาจจะไม่ตอบคำถาม แต่ถ้าเป็นเรื่องจริง (และฉันก็ไม่แน่ใจด้วยซ้ำ) มันเป็นประวัติศาสตร์ที่สนุกสนาน

ในช่วงแรก ๆ ของ Oracle นักพัฒนาคนหนึ่งตระหนักว่าเขาจำเป็นต้องทำซ้ำทุกแถวในตาราง (เช่นเป็นไปได้ว่าเป็นตารางเหตุการณ์และเขาจำเป็นต้องเปลี่ยน "เหตุการณ์เริ่มต้น" และ "เหตุการณ์สิ้นสุด" แยกจากกัน รายการ). เขาตระหนักว่าถ้าเขามีโต๊ะเพียงสองแถวเขาสามารถทำการรวมแบบไขว้โดยเลือกเฉพาะคอลัมน์ในตารางแรกและได้รับสิ่งที่ต้องการ ดังนั้นเขาจึงสร้างตารางง่ายๆซึ่งเขาเรียกว่า "DUAL" อย่างเป็นธรรมชาติ

ต่อมาเขาต้องทำอะไรบางอย่างที่ทำได้โดยการเลือกจากโต๊ะเท่านั้นแม้ว่าการกระทำนั้นจะไม่เกี่ยวข้องกับโต๊ะเลยก็ตาม (บางทีเขาอาจลืมนาฬิกาและต้องการอ่านเวลาผ่านทาง SELECT SYSDATE FROM .. .) เขาตระหนักว่าเขายังคงมีโต๊ะ DUAL นอนอยู่รอบ ๆ และใช้สิ่งนั้น หลังจากนั้นไม่นานเขาเบื่อที่จะเห็นเวลาที่พิมพ์สองครั้งดังนั้นในที่สุดเขาจึงลบหนึ่งในแถว

คนอื่น ๆ ที่ Oracle เริ่มใช้ตารางของเขาและในที่สุดก็ตัดสินใจที่จะรวมไว้ในการติดตั้ง Oracle มาตรฐาน

ซึ่งอธิบายว่าเหตุใดตารางที่มีความสำคัญเพียงอย่างเดียวคือมีแถวเดียวจึงมีชื่อซึ่งแปลว่า "สอง"


9

กุญแจสำคัญคือ "แสดงชุดค่าผสมที่เป็นไปได้ทั้งหมด" ฉันใช้สิ่งเหล่านี้ร่วมกับฟิลด์จากการคำนวณอื่น ๆ ที่เรียงลำดับ / กรองแล้ว

ตัวอย่างเช่นสมมติว่าคุณกำลังสร้างแอปพลิเคชัน arbitrage (การซื้อขาย) คุณมีผู้ขายเสนอสินค้าในราคาและผู้ซื้อขอสินค้าโดยเสียค่าใช้จ่าย คุณทำการรวมข้ามรหัสผลิตภัณฑ์ (เพื่อจับคู่ผู้ซื้อและผู้ขายที่มีศักยภาพ) คำนวณสเปรดระหว่างต้นทุนและราคาจากนั้นจัดเรียงรายละเอียด เพื่อให้คุณ (คนกลาง) มีการซื้อขายที่ทำกำไรได้มากที่สุดในการดำเนินการ เกือบทุกครั้งคุณจะมีเกณฑ์การกรองขอบเขตอื่น ๆ แน่นอน


อา! คำอธิบายนี้เหมาะสมกับฉันมากที่สุด ในกรณีนี้การเข้าร่วมภายในไม่สมเหตุสมผลเนื่องจากไม่มีความสัมพันธ์ระหว่างรหัสผลิตภัณฑ์และผู้ขายเนื่องจากผู้ขายหลายรายสามารถขายผลิตภัณฑ์เดียวกันได้
moonman239

3

ใช้เวลาบางอย่างเช่นตารางหลักซึ่งมีสิบแถวสำหรับตัวเลข 0-9 คุณสามารถใช้การรวมแบบไขว้บนตารางนั้นได้สองสามครั้งเพื่อให้ได้ผลลัพธ์ที่มีหลายแถวที่คุณต้องการโดยมีหมายเลขผลลัพธ์ที่เหมาะสม สิ่งนี้มีประโยชน์หลายประการ ตัวอย่างเช่นคุณสามารถรวมเข้ากับฟังก์ชัน datadd () เพื่อให้ได้ชุดสำหรับทุกวันในปีที่กำหนด


2

วิธีนี้เป็นวิธีที่น่าสนใจที่จะใช้จ่ายเข้าร่วมในการสร้างรายงานแบบแท็บไขว้ ฉันพบมันในSQL For Smarties ของ Joe Celkoและได้ใช้มันหลายครั้ง ใช้เวลาตั้งค่าเล็กน้อย แต่คุ้มค่ากับเวลาที่ลงทุนไป


1

ลองนึกภาพว่าคุณมีชุดคำถามที่คุณต้องการจะออกจากรายการและวันที่ที่ต้องการรวมกัน (ราคาความพร้อมใช้งาน ฯลฯ .. ) คุณสามารถโหลดรายการและวันที่ลงในตารางชั่วคราวแยกกันและให้คำค้นหาของคุณเข้าร่วมตาราง สิ่งนี้อาจสะดวกกว่าทางเลือกในการระบุรายการและวันที่ในคำสั่ง IN โดยเฉพาะอย่างยิ่งเนื่องจากฐานข้อมูลบางแห่ง จำกัด จำนวนองค์ประกอบในประโยค IN


1

คุณสามารถใช้CROSS JOINเพื่อ: - สร้างข้อมูลเพื่อวัตถุประสงค์ในการทดสอบ - รวมคุณสมบัติทั้งหมด - คุณต้องการการผสมผสานที่เป็นไปได้ทั้งหมดเช่นกลุ่มเลือด (A, B, .. ) กับ Rh - / + ฯลฯ ... - ปรับแต่ง สำหรับวัตถุประสงค์ของคุณ;) - ฉันไม่เชี่ยวชาญในด้านนี้;)

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;
  • สร้างการรวมสำหรับ 2 ตารางโดยไม่มีรหัสทั่วไปแล้วจัดกลุ่มโดยใช้ max () ฯลฯ เพื่อค้นหาชุดค่าผสมที่เป็นไปได้สูงสุด
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.