Có một MySQL tương đương với mệnh đề VỚI trong Oracle không?
Có một MySQL tương đương với mệnh đề VỚI trong Oracle không?
Câu trả lời:
Không có. Trừ khi (cho đến khi) một người phát triển nó (MySQL là nguồn mở, bất kỳ ai cũng có thể đóng góp.)
WITH
Từ khóa SQL ANSI / ISO được sử dụng để xác định Biểu thức bảng chung (CTE) và nó đơn giản hóa các truy vấn phức tạp với một hoặc một số tham chiếu lồng nhau. Nó có sẵn trong Oracle, Postgres, SQL-Server, DB2 nhưng không có trong MySQL.
Truy vấn cuối cùng có thể có các tham chiếu (thường là trong FROM
mệnh đề nhưng chúng có thể nằm trong bất kỳ phần nào khác) cho bất kỳ ai trong các biểu thức bảng chung, một hoặc nhiều lần. Truy vấn có thể được viết (không có CTE) trong MySQL bằng các bảng dẫn xuất nhưng các tham chiếu phải được thực hiện nhiều lần.
Ví dụ về một truy vấn ngớ ngẩn cho thấy tất cả những người sinh ra trong thập niên 50 và trong tháng 7 và số lượng tất cả những người sinh ra trong cùng một năm:
WITH a AS
( SELECT name, birthdate, YEAR(birthdate) AS birthyear
FROM persons
WHERE birthdate >= '1950-01-01' AND birthdate < '1960-01-01'
)
, b AS
( SELECT birthyear, COUNT(*) AS cnt
FROM a
GROUP BY birthyear
)
SELECT a.name, a.birthdate, b.cnt AS number_of_births
FROM a JOIN b
ON a.birthyear = b.birthyear
WHERE MONTH(a.birthdate) = 7 ;
Trong MySQL, nó có thể được viết là:
SELECT a.name, a.birthdate, b.cnt AS number_of_births
FROM
( SELECT name, birthdate, YEAR(birthdate) AS birthyear
FROM persons
WHERE birthdate >= '1950-01-01' AND birthdate < '1960-01-01'
) AS a
JOIN
( SELECT birthyear, COUNT(*) AS cnt
FROM
( SELECT name, birthdate, YEAR(birthdate) AS birthyear
FROM persons
WHERE birthdate >= '1950-01-01' AND birthdate < '1960-01-01'
) AS aa
GROUP BY birthyear
) AS b
ON a.birthyear = b.birthyear
WHERE MONTH(a.birthdate) = 7 ;
Lưu ý sự trùng lặp mã cho bảng dẫn xuất a
. Trong các truy vấn phức tạp hơn, mã sẽ phải được viết nhiều lần.
Điều đó sẽ hoạt động nhưng thật đáng tiếc, nó sẽ không cung cấp lợi thế của việc sử dụng mệnh đề VỚI, đó là không thực hiện cùng một truy vấn nhiều lần (với các truy vấn phức tạp có thể thực sự chậm và rất đòi hỏi cho công cụ cơ sở dữ liệu; tôi đã chịu đựng nó) .
Tôi sẽ đề nghị chèn từng CHỌN được xác định trong mệnh đề VỚI ban đầu vào bảng tạm thời của riêng nó và sử dụng chúng trong truy vấn . Trong MySQL, bảng tạm thời sẽ tự hủy sau khi phiên người dùng kết thúc.
BIÊN TẬP:
Tôi chỉ thấy câu trả lời này trong một chủ đề tương tự hiển thị rõ ràng 3 cách giải quyết với MySQL :
/programming//a/1382618/2906290
và một ví dụ về quy trình MySQL tạo và loại bỏ các bảng tạm thời trong trường hợp bạn tiếp tục với phiên của mình và muốn giải phóng các tài nguyên đó (tôi sẽ sử dụng nó như một ví dụ về cú pháp): /programming//a/ 5553145/2906290