Một phép nối chéo thực hiện một tích các-ten trên các bộ giá trị của hai bộ.
SELECT *
FROM Table1
CROSS JOIN Table2
Những trường hợp nào làm cho một hoạt động SQL như vậy đặc biệt hữu ích?
Một phép nối chéo thực hiện một tích các-ten trên các bộ giá trị của hai bộ.
SELECT *
FROM Table1
CROSS JOIN Table2
Những trường hợp nào làm cho một hoạt động SQL như vậy đặc biệt hữu ích?
Câu trả lời:
Nếu bạn có "lưới" mà bạn muốn điền đầy đủ, chẳng hạn như thông tin về kích thước và màu sắc cho một mặt hàng quần áo cụ thể:
select
size,
color
from
sizes CROSS JOIN colors
Có thể bạn muốn một bảng chứa một hàng cho mỗi phút trong ngày và bạn muốn sử dụng nó để xác minh rằng một thủ tục đã được thực thi mỗi phút, vì vậy bạn có thể gạch chéo ba bảng:
select
hour,
minute
from
hours CROSS JOIN minutes
Hoặc bạn có một tập hợp các thông số kỹ thuật báo cáo tiêu chuẩn mà bạn muốn áp dụng hàng tháng trong năm:
select
specId,
month
from
reports CROSS JOIN months
Vấn đề với việc duy trì những quan điểm này là trong hầu hết các trường hợp, bạn không muốn có một sản phẩm hoàn chỉnh, đặc biệt là đối với quần áo. Bạn có thể thêmMINUS
logic vào truy vấn để loại bỏ một số kết hợp nhất định mà bạn không mang theo, nhưng bạn có thể thấy dễ dàng hơn để điền vào bảng theo cách khác và không sử dụng tích Descartes.
Ngoài ra, cuối cùng bạn có thể thử kết hợp chéo trên các bảng có lẽ có nhiều hàng hơn bạn nghĩ, hoặc có lẽ WHERE
mệnh đề của bạn bị thiếu một phần hoặc hoàn toàn. Trong trường hợp đó, DBA của bạn sẽ thông báo ngay cho bạn về sự thiếu sót. Thường thì anh ấy hoặc cô ấy sẽ không hạnh phúc.
Tạo dữ liệu để thử nghiệm.
Bạn thường sẽ không muốn có một sản phẩm Descartes đầy đủ cho hầu hết các truy vấn cơ sở dữ liệu. Toàn bộ sức mạnh của cơ sở dữ liệu quan hệ là bạn có thể áp dụng bất kỳ hạn chế nào mà bạn có thể quan tâm để cho phép bạn tránh kéo các hàng không cần thiết khỏi db.
Tôi giả sử một ví dụ giả định mà bạn có thể muốn đó là nếu bạn có một bảng nhân viên và một bảng công việc cần làm và muốn xem tất cả các nhiệm vụ có thể có của một nhân viên cho một công việc.
Ok, điều này có thể sẽ không trả lời câu hỏi, nhưng, nếu nó là sự thật (và tôi thậm chí không chắc về điều đó) thì đó là một chút thú vị của lịch sử.
Trong những ngày đầu của Oracle, một trong những nhà phát triển nhận ra rằng anh ta cần phải sao chép mọi hàng trong một bảng (ví dụ, có thể đó là một bảng các sự kiện và anh ta cần thay đổi nó thành "sự kiện bắt đầu" và "sự kiện kết thúc" riêng biệt. mục). Anh ta nhận ra rằng nếu anh ta có một bảng chỉ có hai hàng, anh ta có thể thực hiện phép nối chéo, chỉ chọn các cột trong bảng đầu tiên và nhận được chính xác những gì anh ta cần. Vì vậy, anh ấy đã tạo ra một chiếc bàn đơn giản, mà anh ấy gọi là "KÉP" một cách tự nhiên.
Sau đó, anh ta cần phải làm một việc gì đó mà chỉ có thể được thực hiện thông qua lựa chọn từ một bảng, mặc dù bản thân hành động đó không liên quan gì đến bảng, (có lẽ anh ta đã quên đồng hồ và muốn đọc thời gian thông qua CHỌN SYSDATE FROM .. .) Anh ấy nhận ra rằng anh ấy vẫn còn chiếc bàn KÉP của mình nằm xung quanh, và sử dụng nó. Sau một thời gian, anh ta cảm thấy mệt mỏi khi nhìn thấy thời gian được in hai lần, vì vậy anh ta cuối cùng đã xóa một trong các hàng.
Những người khác tại Oracle bắt đầu sử dụng bảng của anh ấy, và cuối cùng, họ đã quyết định đưa nó vào cài đặt Oracle tiêu chuẩn.
Điều này giải thích tại sao một bảng có ý nghĩa duy nhất là nó có một hàng có tên có nghĩa là "hai".
Điều quan trọng là "chỉ cho tôi tất cả các kết hợp có thể có". Tôi đã sử dụng chúng kết hợp với các trường được tính toán khác, sau đó sắp xếp / lọc chúng.
Ví dụ: giả sử bạn đang xây dựng một ứng dụng chênh lệch giá (giao dịch). Bạn có người bán cung cấp sản phẩm ở mức giá và người mua yêu cầu sản phẩm với mức giá. Bạn thực hiện kết hợp chéo trên khóa sản phẩm (để so khớp người mua và người bán tiềm năng), tính toán chênh lệch giữa chi phí và giá cả, sau đó sắp xếp mô tả. về điều này để cung cấp cho bạn (người trung gian) các giao dịch có lợi nhất để thực hiện. Tất nhiên, hầu như lúc nào bạn cũng có các tiêu chí lọc giới hạn khác.
Sử dụng một cái gì đó giống như một bảng chữ số, có mười hàng cho các chữ số 0-9. Bạn có thể sử dụng kết hợp chéo trên bảng đó một vài lần để nhận được kết quả có bao nhiêu hàng bạn cần, với các kết quả được đánh số thích hợp. Điều này có một số cách sử dụng. Ví dụ: bạn có thể kết hợp nó với một hàm datadd () để lấy một tập hợp cho mỗi ngày trong một năm nhất định.
Đây là một cách thú vị để sử dụng kết hợp chéo để tạo báo cáo chéo bảng . Tôi đã tìm thấy nó trong SQL For Smarties của Joe Celko và đã sử dụng nó vài lần. Nó có một chút thiết lập, nhưng đáng để đầu tư thời gian.
Hãy tưởng tượng bạn có một loạt các truy vấn mà bạn muốn đưa ra trên một tổ hợp các mặt hàng và ngày cụ thể (giá cả, tình trạng còn hàng, v.v.). Bạn có thể tải các mục và ngày tháng vào các bảng tạm thời riêng biệt và để các truy vấn của bạn kết hợp chéo với các bảng. Điều này có thể thuận tiện hơn so với việc liệt kê các mục và ngày tháng trong mệnh đề IN, đặc biệt là vì một số cơ sở dữ liệu giới hạn số phần tử trong mệnh đề IN.
bạn có thể sử dụng nó CROSS JOIN để: - tạo dữ liệu cho mục đích thử nghiệm - kết hợp tất cả các thuộc tính - bạn cần tất cả sự kết hợp có thể có, ví dụ như nhóm máu (A, B, ..) với Rh - / +, v.v. - từ đó cho mục đích của bạn;) - Tôi không phải là chuyên gia trong lĩnh vực này;)
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;