การรวมแบบไขว้จะทำผลิตภัณฑ์คาร์ทีเซียนบนสิ่งที่สองของทั้งสองเซ็ต
SELECT *
FROM Table1
CROSS JOIN Table2
สถานการณ์ใดที่ทำให้การดำเนินการ SQL ดังกล่าวมีประโยชน์อย่างยิ่ง?
การรวมแบบไขว้จะทำผลิตภัณฑ์คาร์ทีเซียนบนสิ่งที่สองของทั้งสองเซ็ต
SELECT *
FROM Table1
CROSS JOIN Table2
สถานการณ์ใดที่ทำให้การดำเนินการ SQL ดังกล่าวมีประโยชน์อย่างยิ่ง?
คำตอบ:
หากคุณมี "เส้นตาราง" ที่ต้องการเติมข้อมูลให้ครบถ้วนเช่นข้อมูลขนาดและสีสำหรับเสื้อผ้าชิ้นใดชิ้นหนึ่ง:
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 ของคุณจะแจ้งให้คุณทราบทันทีถึงการละเว้น โดยปกติเขาหรือเธอจะไม่มีความสุข
สร้างข้อมูลสำหรับการทดสอบ
โดยทั่วไปคุณจะไม่ต้องการผลิตภัณฑ์คาร์ทีเซียนแบบเต็มสำหรับการสืบค้นฐานข้อมูลส่วนใหญ่ พลังทั้งหมดของฐานข้อมูลเชิงสัมพันธ์คือคุณสามารถใช้ข้อ จำกัด ใด ๆ ที่คุณอาจสนใจเพื่อให้คุณหลีกเลี่ยงการดึงแถวที่ไม่จำเป็นออกจากฐานข้อมูล
ฉันคิดว่าตัวอย่างที่สร้างขึ้นอย่างหนึ่งที่คุณอาจต้องการนั่นคือถ้าคุณมีโต๊ะพนักงานและตารางงานที่ต้องทำและต้องการดูการมอบหมายงานทั้งหมดที่เป็นไปได้ของพนักงานหนึ่งคนต่อหนึ่งงาน
โอเคนี่อาจจะไม่ตอบคำถาม แต่ถ้าเป็นเรื่องจริง (และฉันก็ไม่แน่ใจด้วยซ้ำ) มันเป็นประวัติศาสตร์ที่สนุกสนาน
ในช่วงแรก ๆ ของ Oracle นักพัฒนาคนหนึ่งตระหนักว่าเขาจำเป็นต้องทำซ้ำทุกแถวในตาราง (เช่นเป็นไปได้ว่าเป็นตารางเหตุการณ์และเขาจำเป็นต้องเปลี่ยน "เหตุการณ์เริ่มต้น" และ "เหตุการณ์สิ้นสุด" แยกจากกัน รายการ). เขาตระหนักว่าถ้าเขามีโต๊ะเพียงสองแถวเขาสามารถทำการรวมแบบไขว้โดยเลือกเฉพาะคอลัมน์ในตารางแรกและได้รับสิ่งที่ต้องการ ดังนั้นเขาจึงสร้างตารางง่ายๆซึ่งเขาเรียกว่า "DUAL" อย่างเป็นธรรมชาติ
ต่อมาเขาต้องทำอะไรบางอย่างที่ทำได้โดยการเลือกจากโต๊ะเท่านั้นแม้ว่าการกระทำนั้นจะไม่เกี่ยวข้องกับโต๊ะเลยก็ตาม (บางทีเขาอาจลืมนาฬิกาและต้องการอ่านเวลาผ่านทาง SELECT SYSDATE FROM .. .) เขาตระหนักว่าเขายังคงมีโต๊ะ DUAL นอนอยู่รอบ ๆ และใช้สิ่งนั้น หลังจากนั้นไม่นานเขาเบื่อที่จะเห็นเวลาที่พิมพ์สองครั้งดังนั้นในที่สุดเขาจึงลบหนึ่งในแถว
คนอื่น ๆ ที่ Oracle เริ่มใช้ตารางของเขาและในที่สุดก็ตัดสินใจที่จะรวมไว้ในการติดตั้ง Oracle มาตรฐาน
ซึ่งอธิบายว่าเหตุใดตารางที่มีความสำคัญเพียงอย่างเดียวคือมีแถวเดียวจึงมีชื่อซึ่งแปลว่า "สอง"
กุญแจสำคัญคือ "แสดงชุดค่าผสมที่เป็นไปได้ทั้งหมด" ฉันใช้สิ่งเหล่านี้ร่วมกับฟิลด์จากการคำนวณอื่น ๆ ที่เรียงลำดับ / กรองแล้ว
ตัวอย่างเช่นสมมติว่าคุณกำลังสร้างแอปพลิเคชัน arbitrage (การซื้อขาย) คุณมีผู้ขายเสนอสินค้าในราคาและผู้ซื้อขอสินค้าโดยเสียค่าใช้จ่าย คุณทำการรวมข้ามรหัสผลิตภัณฑ์ (เพื่อจับคู่ผู้ซื้อและผู้ขายที่มีศักยภาพ) คำนวณสเปรดระหว่างต้นทุนและราคาจากนั้นจัดเรียงรายละเอียด เพื่อให้คุณ (คนกลาง) มีการซื้อขายที่ทำกำไรได้มากที่สุดในการดำเนินการ เกือบทุกครั้งคุณจะมีเกณฑ์การกรองขอบเขตอื่น ๆ แน่นอน
ใช้เวลาบางอย่างเช่นตารางหลักซึ่งมีสิบแถวสำหรับตัวเลข 0-9 คุณสามารถใช้การรวมแบบไขว้บนตารางนั้นได้สองสามครั้งเพื่อให้ได้ผลลัพธ์ที่มีหลายแถวที่คุณต้องการโดยมีหมายเลขผลลัพธ์ที่เหมาะสม สิ่งนี้มีประโยชน์หลายประการ ตัวอย่างเช่นคุณสามารถรวมเข้ากับฟังก์ชัน datadd () เพื่อให้ได้ชุดสำหรับทุกวันในปีที่กำหนด
วิธีนี้เป็นวิธีที่น่าสนใจที่จะใช้จ่ายเข้าร่วมในการสร้างรายงานแบบแท็บไขว้ ฉันพบมันในSQL For Smarties ของ Joe Celkoและได้ใช้มันหลายครั้ง ใช้เวลาตั้งค่าเล็กน้อย แต่คุ้มค่ากับเวลาที่ลงทุนไป
ลองนึกภาพว่าคุณมีชุดคำถามที่คุณต้องการจะออกจากรายการและวันที่ที่ต้องการรวมกัน (ราคาความพร้อมใช้งาน ฯลฯ .. ) คุณสามารถโหลดรายการและวันที่ลงในตารางชั่วคราวแยกกันและให้คำค้นหาของคุณเข้าร่วมตาราง สิ่งนี้อาจสะดวกกว่าทางเลือกในการระบุรายการและวันที่ในคำสั่ง IN โดยเฉพาะอย่างยิ่งเนื่องจากฐานข้อมูลบางแห่ง จำกัด จำนวนองค์ประกอบในประโยค IN
คุณสามารถใช้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;