Tương đương với MySQL trong orory


Câu trả lời:


16

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.)

WITHTừ 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 FROMmệ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.


Để tránh sự lặp lại (sao chép mã), sẽ tốt hơn nếu sử dụng các biến và bảng tạm thời?
Pacerier

Tôi sẽ không lo lắng về việc sao chép mã nhưng chắc chắn tôi sẽ xem xét và thử một phiên bản với các bảng tạm thời, vì lý do hiệu suất.
ypercubeᵀᴹ

1
Tại sao bạn nói rằng bạn sẽ không lo lắng về việc sao chép mã? Điều này là hoàn toàn lộn xộn và không  DRY .
Pacerier

1
@Pacerier DRY không phải lúc nào cũng phù hợp với mã DB.
JNK

1
@Pacerier Tôi sẽ không ngạc nhiên nếu không. Các công cụ DB cần đưa ra những phỏng đoán có giáo dục về những gì sẽ hoạt động tốt nhất trong khi vẫn đảm bảo trả về kết quả chính xác. Các bảng tạm thời nói chung là tốt, nhưng DRY dẫn đến hiệu suất khủng trong DB ở các khía cạnh khác, như các hàm do người dùng xác định.
JNK

2

Đ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 :

  • Bảng TẠM THỜI
  • Bảng DERIVED
  • Chế độ xem nội tuyến (hiệu quả của mệnh đề VỚI thể hiện - chúng có thể hoán đổi cho nhau)

/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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.