Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

MySQL 8 Biểu thức Bảng Phổ biến CTE

MySQL 8 hỗ trợ các biểu thức bảng phổ biến, cả không đệ quy và đệ quy, CTE (Biểu thức bảng chung) là một tập kết quả tạm thời mà bạn có thể tham chiếu trong một câu lệnh SELECT, INSERT, UPDATE hoặc DELETE khác.

CTE không đệ quy

Một biểu thức bảng chung (CTE) cũng giống như một bảng dẫn xuất, nhưng phần khai báo của nó được đặt trước khối truy vấn thay vì trong mệnh đề FROM. Sử dụng CTE, truy vấn con chỉ được đánh giá một lần, Biểu thức bảng chung cho phép sử dụng các tập kết quả tạm thời được đặt tên, Biểu thức bảng chung được xác định trong câu lệnh bằng toán tử WITH.

Giả sử bạn muốn tìm hiểu tỷ lệ phần trăm thay đổi trong các khoản thanh toán của mỗi năm so với năm trước. Nếu không có CTE, bạn cần viết hai truy vấn con và chúng về cơ bản giống nhau. MySQL không đủ thông minh để phát hiện điều đó và các truy vấn con được thực thi hai lần.

 CHỌN q1.years, q2.years AS next_year, q1.sum1, q2.sum1 AS next_sum, 100 * (q2.sum1 - q1.sum1) / q1.sum1 AS pctFROM (CHỌN NĂM (ngày thanh toán) AS năm, TỔNG (số tiền) NHƯ tổng1 TỪ khoản thanh toán NHÓM THEO năm) NHƯ q1, (CHỌN NĂM (ngày thanh toán) NHƯ năm, SUM (số tiền) NHƯ tổng1 TỪ khoản thanh toán NHÓM THEO năm) NHƯ q2WHEREq1.years =q2.years - 1; + - ----- + ----------- + ------------ + ------------ + ------ ------ + | năm | năm sau | sum1 | next_sum | pct | + ------- + ----------- + ------------ + ------------ + - ----------- + | Năm 2003 | Năm 2004 | 3250217.70 | 4313328,25 | 32,708903 || Năm 2004 | Năm 2005 | 4313328,25 | 1290293.28 | -70.085901 | + ------- + ----------- + ------------ + ------------ + ------------ + 2 hàng trong bộ (0,01 giây) 

Với CTE không đệ quy, truy vấn dẫn xuất chỉ được thực thi một lần và được sử dụng lại

 VỚI CTE_NAME AS (CHỌN NĂM (ngày thanh toán) NHƯ năm, SUM (số tiền) NHƯ tổng1 TỪ khoản thanh toán NHÓM THEO năm) CHỌN q1.years, q2.years AS next_year, q1.sum1, q2.sum1 AS next_sum, 100 * (q2.sum1 - q1.sum1) / q1.sum1 AS pct TỪ CTE_NAME AS q1, CTE_NAME AS q2 WHERE q1.years =q2.years - 1; + ------- + ------- ---- + ------------ + ------------ + ------------ + | năm | năm sau | sum1 | next_sum | pct | + ------- + ----------- + ------------ + ------------ + - ----------- + | Năm 2003 | Năm 2004 | 3250217.70 | 4313328,25 | 32,708903 || Năm 2004 | Năm 2005 | 4313328,25 | 1290293.28 | -70.085901 | + ------- + ----------- + ------------ + ------------ + ------------ + 2 hàng trong bộ (0,00 giây) 

Bạn có thể nhận thấy rằng với CTE, kết quả giống nhau và thời gian truy vấn cải thiện 50%, khả năng đọc tốt và có thể được tham chiếu nhiều lần

 CTE có thể tham chiếu đến các CTE khác:WITH cte1 AS (SELECT ... FROM ...), cte2 AS (SELECT ... FROM cte1 ...) SELECTFROM cte1, cte2 ... 

CTE đệ quy

CTE đệ quy là một CTE tham chiếu đến chính nó. Khi làm như vậy, CTE ban đầu được thực thi lặp đi lặp lại, trả về các tập dữ liệu con, cho đến khi trả về kết quả hoàn chỉnh

 WITH RECURSIVE cte_name AS (cte_definition - / * seed SELECT * / UNION ALLcte_definition - / * "recursive" SELECT * / reference cte_name.) - Câu lệnh sử dụng CTESELECT * FROM cte_name 

Seed SELECT được thực thi một lần để tạo tập con dữ liệu ban đầu; đệ quy SELECT được thực thi lặp đi lặp lại để trả về các tập dữ liệu con cho đến khi thu được tập kết quả hoàn chỉnh. Đệ quy dừng khi một phép lặp không tạo ra bất kỳ hàng mới nào.

Giả sử bạn muốn thực hiện truyền dữ liệu phân cấp để tạo ra một sơ đồ tổ chức với chuỗi quản lý cho từng nhân viên (nghĩa là con đường từ CEO đến một nhân viên). Sử dụng một CTE đệ quy! CTE đệ quy rất phù hợp để truy vấn dữ liệu phân cấp,

Tạo bảng

 TẠO BẢNG mangeremp (id INT PRIMARY KEY NOT NULL, name VARCHAR (100) NOT NULL, man_id INT NULL, INDEX (man_id), FOREIGN KEY (man_id) TÀI LIỆU THAM KHẢO mangeremp (id)); 

chèn dữ liệu để có được cấu trúc phân cấp

 CHÈN VÀO CÁC GIÁ TRỊ mangeremp (333, "waqas", NULL), # waqas là CEO (man_id là NULL) (198, "ali", 333), # ali có ID 198 và báo cáo đến 333 (waqas) ( 692, "ahmed", 333), #ahmed báo cáo cho waqas (29, "oasama", 198), #osama báo cáo cho ali vì alo có id ref 198 (4610, "Mughees", 29), # Mughees báo cáo cho osama (72, "aslam", 29), (123, "afrooz", 692); 
 VỚI RECURSIVE emp_paths (id, name, path) AS (SELECT id, name, CAST (id AS CHAR (200)) FROM mangeremp TẠI ĐÓ man_id LÀ KHÔNG ĐỐI VỚI TẤT CẢ CHỌN e.id, e.name, CONCAT (ep. path, ',', e.id) FROM emp_paths AS ep JOIN mangeremp AS e ON ep.id =e.man_id) SELECT * FROM emp_paths ORDER BY path; + ------ + ------- - + ----------------- + | id | tên | đường dẫn | + ------ + --------- + ----------------- + | 333 | waqas | 333 || 198 | ali | 333,198 || 29 | oasama | 333,198,29 || 4610 | Mughees | 333,198,29,4610 || 72 | aslam | 333,198,29,72 || 692 | ahmed | 333,692 || 123 | afrooz | 333,692,123 | + ------ + --------- + ----------------- + 7 hàng trong bộ (0,00 giây) 
 SELECT e.id, e.name, CONCAT (ep.path, ',', e.id) FROM emp_paths AS ep JOIN mangeremp AS e ON ep.id =e.man_id ---- truy vấn đệ quy  

Mỗi hàng được tạo bởi truy vấn đệ quy tìm tất cả các nhân viên báo cáo trực tiếp cho một
nhân viên được tạo bởi một hàng trước đó. Đối với mỗi nhân viên như vậy, hàng bao gồm ID nhân viên, tên và chuỗi quản lý nhân viên. Chuỗi là chuỗi
của người quản lý với ID nhân viên được thêm vào cuối


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Làm cách nào để thoát ký hiệu phần trăm theo nghĩa đen khi tùy chọn NO_BACKSLASH_ESCAPES được bật?

  2. Làm cách nào để truy xuất phiên bản hiện tại của hệ quản trị cơ sở dữ liệu MySQL (DBMS)?

  3. Làm cách nào để nhập tệp SQL bằng dòng lệnh trong MySQL?

  4. Cách thực hiện chèn hàng loạt trong MySQL

  5. Nhân rộng MySQL để có tính khả dụng cao