Các truy vấn con có thêm sức mạnh biểu cảm cho các truy vấn SQL không?


29

SQL có cần truy vấn con không?

Hãy tưởng tượng một triển khai đủ khái quát của ngôn ngữ truy vấn có cấu trúc cho các cơ sở dữ liệu quan hệ. Do cấu trúc của câu lệnh SQL chuẩn SELECTthực sự rất quan trọng đối với điều này có ý nghĩa, nên tôi không kháng cáo trực tiếp với đại số quan hệ, nhưng bạn có thể đóng khung điều này theo các thuật ngữ đó bằng cách đưa ra các hạn chế phù hợp về hình thức biểu thức.

Một SQL SELECTtruy vấn thông thường bao gồm một chiếu (các SELECTphần) một số số JOINhoạt động (các JOINphần), một số số SELECTION hoạt động (trong SQL, các WHEREđiều khoản), và sau đó đặt khôn ngoan hoạt động ( UNION, EXCEPT, INTERSECT, vv), tiếp theo là một SELECTTruy vấn SQL .

Các bảng được nối có thể là kết quả tính toán của các biểu thức; nói cách khác, chúng ta có thể có một tuyên bố như:

SELECT t1.name, t2.address
  FROM table1 AS t1 
  JOIN (SELECT id, address 
          FROM table2 AS t3 
         WHERE t3.id = t1.id) AS t2
 WHERE t1.salary > 50,000;

Chúng tôi sẽ đề cập đến việc sử dụng bảng được tính toán như một phần của truy vấn SQL dưới dạng truy vấn con. Trong ví dụ trên, thứ hai (thụt lề) SELECTlà một truy vấn con.

Tất cả các truy vấn SQL có thể được viết theo cách không sử dụng các truy vấn con không? Ví dụ trên có thể:

SELECT t1.name, t2.address
  FROM table1 AS t1 
  JOIN table2 AS t2
    ON t1.id = t2.id
 WHERE t1.salary > 50,000;

Ví dụ này có phần giả mạo hoặc tầm thường, nhưng người ta có thể tưởng tượng các trường hợp trong đó cần nhiều nỗ lực hơn để phục hồi một biểu thức tương đương. Nói cách khác, có phải là trường hợp đối với mọi truy vấn SQL với các truy vấn con, tồn tại một truy vấn q không có các truy vấn con sao cho q và được đảm bảo tạo ra kết quả giống nhau cho cùng các bảng bên dưới không? Hãy để chúng tôi giới hạn các truy vấn SQL ở dạng sau:qq'qq'

SELECT <attribute>,
      ...,
      <attribute>
 FROM <a table, not a subquery>
 JOIN <a table, not a subquery>
  ...
 JOIN <a table, not a subquery>
WHERE <condition>
  AND <condition>
  ...
  AND <condition>

UNION
 -or-
EXCEPT
 -or-
<similar>

SELECT ...

Và như vậy. Tôi nghĩ rằng các kết nối bên trái và bên phải không thêm nhiều, nhưng nếu tôi nhầm, xin vui lòng chỉ ra rằng ... trong bất kỳ sự kiện nào, chúng cũng là trò chơi công bằng. Theo như các hoạt động đã định, tôi đoán bất kỳ trong số chúng đều ổn ... liên kết, khác biệt, khác biệt đối xứng, giao nhau, v.v ... bất cứ điều gì hữu ích. Có bất kỳ biểu mẫu đã biết nào mà tất cả các truy vấn SQL có thể được giảm không? Có bất kỳ trong số các loại bỏ các truy vấn con? Hoặc có một số trường hợp không tồn tại truy vấn tương đương, truy vấn không có truy vấn phụ? Tài liệu tham khảo được đánh giá cao ... hoặc một minh chứng (bằng chứng) rằng chúng là hoặc không bắt buộc sẽ là tuyệt vời. Cảm ơn, và xin lỗi nếu đây là một kết quả nổi tiếng (hoặc tầm thường) mà tôi không biết gì.


5
Ruột của tôi nói với tôi rằng bạn luôn có thể tham gia cùng nhau mọi thứ và chọn từ đó miễn là bạn không cần các giá trị tổng hợp. Chọn tất cả các mục có giá trị lớn hơn mức trung bình của cột dường như yêu cầu tính toán trung bình trước, do đó cần một truy vấn con.
Raphael

@Raphael Tôi khá chắc chắn rằng bạn thậm chí có thể thực hiện các giá trị tổng hợp, bạn chỉ cần thực hiện nhiều lần tự tham gia và theo nhóm (làm cho nó lớn hơn theo cấp số nhân, nhưng vẫn có thể). Dù vậy, không chắc chắn làm thế nào tôi chính thức chứng minh bạn có thể làm mọi thứ theo cách đó.
Kevin

@Kevin Bạn có chắc số lượng thao tác cần thiết không phụ thuộc vào số lượng hàng? Bởi vì chúng ta không thể có điều đó, phải không?
Raphael

1
Ví dụ bình thường tôi có để yêu cầu truy vấn con là đếm các bản sao : select count(*) from (select id from sometable group by id having count(*)>1) d. Bởi vì nó bao gồm group bytôi đã không đặt điều này như một câu trả lời.
Đánh dấu Hurd

BTW AFAIK trong SQL bình thường, ONmệnh đề được yêu cầu cho JOINs, mặc dù một sản phẩm chéo có được chỉ bằng dấu phẩy.
Đánh dấu Hurd

Câu trả lời:


9

Có một số thuật ngữ nhầm lẫn; khối truy vấn trong ngoặc đơn

SELECT t1.name, t2.address
  FROM table1 
  JOIN (SELECT id, address 
          FROM table2 AS t3 
         WHERE t3.id = t1.id) 

được gọi là quan điểm bên trong . Một subquery là khối truy vấn trong vòng hai WHERE hoặc mệnh đề SELECT, ví dụ:

select deptno from dept
where 3 < (select count(1) from emp 
           where dept.deptno=emp.deptno)

Trong cả hai trường hợp, chế độ xem bên trong hoặc truy vấn con có thể không được kiểm tra thành tham gia dự án "phẳng". Truy vấn con tương quan với tổng hợp không cần thiết vào các khung nhìn bên trong với nhóm, sau đó không cần thiết vào truy vấn phẳng.

select deptno from dept d
    where 3 < (select avg(sal) from emp e
               where d.deptno=e.deptno)

select d.deptno from dept d, ( 
    select deptno from emp e
    group by deptno
    having avg(sal) > 3
) where d.deptno=e.deptno

select d.deptno from dept d, emp e
where d.deptno=e.deptno 
group by d.deptno
having avg(sal) > 3

Đối với các quy tắc đại số để tối ưu hóa truy vấn, đại số quan hệ được biết là được axiomatized thành Mạng quan hệ giúp đơn giản hóa các biến đổi truy vấn như được trình bày ở đâyở đó .


Tôi tò mò. Bạn có thể thêm một ví dụ về truy vấn sử dụng một số trường trung bình không, ví dụ: chọn tất cả các mục có giá trị trên trung bình? Nó không rõ ràng với tôi như thế nào sau khi làm phẳng.
Raphael

16

Để dịch câu lệnh của bạn sang đại số quan hệ, tôi nghĩ nó hỏi:

σMột(Một)σB(B)σMột(σB(MộtB))

σ

Câu trả lời là "Có" và đó là tối ưu hóa truy vấn tiêu chuẩn. Thành thật mà nói, tôi không chắc làm thế nào để chứng minh điều này theo cách không phải là câu hỏi - đó chỉ là một tài sản của sự lựa chọn và tham gia. Bạn có thể lập luận theo quy nạp để thêm tuy nhiên nhiều lớp truy vấn lồng nhau mà bạn muốn.

Ngoài ra, bạn có thể hỏi:

MộtBCGiáo dục(MộtB)(CD)

Một lần nữa câu trả lời là có, bởi vì tham gia là kết hợp. Báo cáo tương tự có thể được thực hiện về chiếu.

Một loại "truy vấn con" đáng chú ý mà tôi nghĩ không thể "làm phẳng" là with. Một cách để thấy điều này là lưu ý rằng nếu bạn có một withcâu lệnh thì bạn có thể có một hàm đệ quy, không thể được viết mà không sử dụng các truy vấn con.

Vì vậy, để tóm tắt: trong trường hợp cụ thể mà bạn đã đề cập, không, SQL không cần truy vấn con và bạn có thể chứng minh nó theo quy nạp. Nhìn chung, có những tính năng yêu cầu truy vấn con.


Hành vi đệ quy thông qua withđã được giới thiệu trong SQL: 1999 và làm cho ngôn ngữ kết quả trở nên biểu cảm hơn.
András Salamon

1

"Các truy vấn con có thêm sức mạnh biểu cảm cho các truy vấn SQL không?"

Họ đã làm, ít nhất là trước khi giới thiệu EXCEPT bằng ngôn ngữ SQL.

Trước khi giới thiệu EXCEPT, không có cách nào để thể hiện sự khác biệt quan hệ hoặc bán chính xác trong SQL mà không dùng đến các truy vấn con.

Ngày nay, tất cả các toán tử nguyên thủy "điển hình" của "đại số quan hệ" có thể được biểu diễn mà không cần truy vấn con:

TỰ NHIÊN tham gia có thể được thực hiện thông qua NGUYÊN JOIN, hoặc THAM GIA VỀ
UNION có thể được thực hiện thông qua UNION
TRỪ có thể được thực hiện thông qua TRỪ
DỰ ÁN / RENAME / mở rộng có thể được thực hiện throug CHỌN
hạn chế có thể được thực hiện thông qua ĐÂU
literals quan hệ có thể được thực hiện thông qua GIÁ TRỊ
bắc cầu đóng cửa có thể được thực hiện thông qua đệ quy VỚI

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.