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

PostgreSQL - Không truy vấn phụ có liên quan?

Một vài điểm quan trọng về cách sử dụng SQL:

  • Bạn không thể sử dụng bí danh cột trong mệnh đề WHERE, nhưng bạn có thể sử dụng bí danh trong mệnh đề HAVING. Đó là nguyên nhân gây ra lỗi mà bạn mắc phải.
  • Bạn có thể thực hiện công việc đếm của mình bằng cách sử dụng JOIN và GROUP BY tốt hơn so với bằng cách sử dụng các truy vấn con có liên quan. Nó sẽ nhanh hơn nhiều.
  • Sử dụng mệnh đề HAVING để lọc các nhóm.

Đây là cách tôi viết truy vấn này:

SELECT t1.id, COUNT(t2.id) AS num_things
FROM t1 JOIN t2 USING (id)
GROUP BY t1.id
HAVING num_things = 5;

Tôi nhận thấy rằng truy vấn này có thể bỏ qua JOIN với t1, như trong giải pháp của Charles Bretana. Nhưng tôi cho rằng bạn có thể muốn truy vấn bao gồm một số cột khác từ t1.

Re:câu hỏi trong bình luận:

Sự khác biệt là WHERE mệnh đề được đánh giá trên các hàng, trước GROUP BY giảm các nhóm xuống một hàng cho mỗi nhóm. HAVING mệnh đề được đánh giá sau khi các nhóm được thành lập. Vì vậy, ví dụ:bạn không thể thay đổi COUNT() của một nhóm bằng cách sử dụng HAVING; bạn chỉ có thể loại trừ chính nhóm đó.

SELECT t1.id, COUNT(t2.id) as num
FROM t1 JOIN t2 USING (id)
WHERE t2.attribute = <value>
GROUP BY t1.id
HAVING num > 5;

Trong truy vấn trên, WHERE bộ lọc cho các hàng phù hợp với một điều kiện và HAVING bộ lọc cho các nhóm có ít nhất năm số lượng.

Điểm khiến hầu hết mọi người nhầm lẫn là khi họ không có GROUP BY mệnh đề, vì vậy nó có vẻ như như HAVINGWHERE có thể hoán đổi cho nhau.

WHERE được đánh giá trước các biểu thức trong danh sách chọn. Điều này có thể không rõ ràng vì cú pháp SQL đặt danh sách chọn lên đầu tiên. Vì vậy, bạn có thể tiết kiệm rất nhiều tính toán tốn kém bằng cách sử dụng WHERE để hạn chế hàng.

SELECT <expensive expressions>
FROM t1
HAVING primaryKey = 1234;

Nếu bạn sử dụng truy vấn như trên, các biểu thức trong danh sách chọn được tính cho mọi hàng , chỉ để loại bỏ hầu hết các kết quả do HAVING tình trạng. Tuy nhiên, truy vấn bên dưới chỉ tính biểu thức cho hàng đơn khớp với WHERE điều kiện.

SELECT <expensive expressions>
FROM t1
WHERE primaryKey = 1234;

Vì vậy, tóm lại, các truy vấn được chạy bởi công cụ cơ sở dữ liệu theo một loạt các bước:

  1. Tạo tập hợp các hàng từ (các) bảng, bao gồm bất kỳ hàng nào được tạo bởi JOIN .
  2. Đánh giá WHERE điều kiện so với tập hợp các hàng, lọc ra các hàng không khớp.
  3. Tính toán các biểu thức trong danh sách chọn cho từng biểu thức trong tập hợp các hàng.
  4. Áp dụng bí danh cột (lưu ý đây là một bước riêng biệt, có nghĩa là bạn không thể sử dụng bí danh trong các biểu thức trong danh sách chọn).
  5. Thu gọn các nhóm thành một hàng cho mỗi nhóm, theo GROUP BY mệnh đề.
  6. Đánh giá HAVING điều kiện chống lại các nhóm, lọc ra các nhóm không phù hợp.
  7. Sắp xếp kết quả, theo ORDER BY mệnh đề.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. postgres - trong (danh sách) - cột không tồn tại

  2. Postgres không thể nghe một địa chỉ IP cụ thể

  3. Lọc theo phạm vi ngày (cùng tháng và ngày) qua các năm

  4. Trong Spring Boot 2, có thể tự động tạo một JoinTable với một ràng buộc duy nhất không?

  5. Postgresql:Tạo trình tự