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

Cách lọc kết quả truy vấn trong PostgreSQL


Giới thiệu

Để làm việc với dữ liệu trong cơ sở dữ liệu, bạn cần có khả năng truy xuất và nhắm mục tiêu các bản ghi cụ thể một cách hiệu quả. Bằng cách sử dụng các mệnh đề lọc trong các truy vấn của mình, bạn có thể thêm các tiêu chí cụ thể để chỉ trả lại các bản ghi có liên quan nhất.

Trong hướng dẫn này, chúng ta sẽ xem xét một số hoạt động lọc phổ biến nhất có sẵn trong PostgreSQL và trình bày cách sử dụng chúng để thu hẹp trọng tâm của các câu lệnh của bạn. Chúng tôi sẽ chỉ ra cách kiểm tra các đặc điểm trong các bản ghi riêng lẻ với WHERE mệnh đề, cách nhóm các bản ghi lại với nhau để tóm tắt thông tin với GROUP BY , cách lọc các nhóm bản ghi với HAVING điều khoản phụ và cách đặt số lượng hàng trả về tối đa với LIMIT mệnh đề.



Sử dụng WHERE mệnh đề xác định tiêu chí đối sánh

Một trong những cách phổ biến và hữu ích nhất để chỉ ra các yêu cầu truy vấn của bạn là WHERE mệnh đề. WHERE mệnh đề cho phép bạn xác định tiêu chí tìm kiếm thực tế cho các câu lệnh truy vấn bằng cách chỉ định các điều kiện phải đúng cho tất cả các bản ghi phù hợp.

WHERE mệnh đề hoạt động bằng cách xác định các biểu thức boolean được kiểm tra dựa trên mỗi hàng dữ liệu ứng viên. Nếu kết quả của biểu thức là false, hàng sẽ bị xóa khỏi kết quả và không được trả về hoặc tiếp tục đến giai đoạn xử lý tiếp theo. Nếu kết quả của biểu thức là true, nó đáp ứng các tiêu chí của tìm kiếm và sẽ tiếp tục được xử lý thêm với tư cách là một hàng ứng viên.

Cú pháp cơ bản của WHERE mệnh đề giống như sau:

SELECT * FROM my_table WHERE <condition>;

<condition> có thể là bất kỳ thứ gì dẫn đến giá trị boolean. Trong PostgreSQL, giá trị boolean là bất kỳ giá trị nào trong số TRUE , FALSE hoặc NULL .

Các điều kiện thường được hình thành bằng cách sử dụng một hoặc nhiều toán tử sau:

  • = :bằng
  • > :lớn hơn
  • < :nhỏ hơn
  • >= :lớn hơn hoặc bằng
  • <= :nhỏ hơn hoặc bằng
  • <> hoặc != :không bằng
  • AND :toán tử logic "và" - kết hợp hai điều kiện và trả về TRUE nếu cả hai điều kiện đều TRUE
  • OR :toán tử logic "hoặc" - kết hợp hai điều kiện và trả về TRUE nếu ít nhất một trong các điều kiện TRUE
  • IN :giá trị được chứa trong danh sách, chuỗi hoặc dải ô theo sau
  • BETWEEN :giá trị được chứa trong phạm vi các giá trị tối thiểu và tối đa theo sau, bao gồm cả
  • IS NULL :khớp nếu giá trị là NULL
  • NOT :phủ định giá trị boolean theo sau
  • EXISTS :truy vấn theo sau chứa kết quả
  • LIKE :khớp với một mẫu (sử dụng các ký tự đại diện % để khớp với 0 hoặc nhiều ký tự và _ để khớp với một ký tự)
  • ILIKE :khớp với một mẫu (sử dụng các ký tự đại diện % để khớp với 0 hoặc nhiều ký tự và _ để khớp với một ký tự), không phân biệt chữ hoa chữ thường
  • SIMILAR TO :khớp với một mẫu sử dụng phương ngữ biểu thức chính quy của SQL
  • ~ :đối sánh với một mẫu sử dụng biểu thức chính quy POSIX, phân biệt chữ hoa chữ thường
  • ~* :đối sánh với một mẫu sử dụng biểu thức chính quy POSIX, không phân biệt chữ hoa chữ thường
  • !~ :không khớp với mẫu sử dụng biểu thức chính quy POSIX, phân biệt chữ hoa chữ thường
  • !~* :không khớp với mẫu sử dụng biểu thức chính quy POSIX, không phân biệt chữ hoa chữ thường

Trong khi danh sách trên đại diện cho một số cấu trúc kiểm tra phổ biến nhất, có nhiều toán tử khác mang lại kết quả boolean có thể được sử dụng cùng với WHERE mệnh đề.


Ví dụ sử dụng WHERE

Một trong những cách kiểm tra đơn giản và phổ biến nhất là kiểm tra tính bình đẳng, sử dụng = nhà điều hành. Tại đây, chúng tôi kiểm tra xem từng hàng trong customer bảng có last_name giá trị bằng Smith :

SELECT * FROM customer WHERE last_name = 'Smith';

Chúng ta có thể thêm các điều kiện bổ sung vào điều này để tạo các biểu thức ghép bằng cách sử dụng các toán tử logic. Ví dụ này sử dụng AND mệnh đề để thêm một bài kiểm tra bổ sung đối với first_name cột. Các hàng hợp lệ phải thỏa mãn cả hai điều kiện đã cho:

SELECT * FROM customer WHERE first_name = 'John' AND last_name = 'Smith';

Tương tự, chúng ta có thể kiểm tra xem có đáp ứng bất kỳ điều kiện nào trong số một loạt điều kiện hay không. Tại đây, chúng tôi kiểm tra các hàng từ địa chỉ address để xem liệu zip_code giá trị bằng 60626 hoặc neighborhood cột bằng chuỗi "Roger Park". Chúng tôi sử dụng hai dấu ngoặc kép đơn để chỉ ra rằng một dấu ngoặc kép theo nghĩa đen nên được tìm kiếm:

SELECT * FROM address WHERE zip_code = '60626' OR neighborhood = 'Roger''s Park';

IN toán tử có thể hoạt động giống như một phép so sánh giữa một số giá trị, được bao bọc trong dấu ngoặc đơn. Nếu khớp với bất kỳ giá trị nào trong số các giá trị đã cho, biểu thức là TRUE :

SELECT * FROM customer WHERE last_name IN ('Smith', 'Johnson', 'Fredrich');

Ở đây, chúng tôi kiểm tra một mẫu chuỗi bằng cách sử dụng LIKE . % hoạt động như một ký tự đại diện khớp với không hoặc nhiều ký tự, vì vậy "Pete", "Peter" và bất kỳ chuỗi nào khác bắt đầu bằng "Pete" sẽ khớp:

SELECT * FROM customer WHERE last_name LIKE 'Pete%';

Chúng tôi có thể thực hiện một tìm kiếm tương tự bằng cách sử dụng ~* toán tử để kiểm tra các kết quả phù hợp bằng cách sử dụng biểu thức chính quy POSIX mà không phân biệt chữ hoa, chữ thường. Trong trường hợp này, chúng tôi kiểm tra xem giá trị của last_name bắt đầu bằng "d" và chứa chuỗi con "on", sẽ khớp với các tên như "Dickson", "Donald" và "Devon":

SELECT * FROM customer WHERE last_name ~* '^D.*on.*';

Chúng tôi có thể kiểm tra xem một số đường phố có nằm trong khối 4000 địa chỉ hay không bằng cách sử dụng BETWEENAND toán tử để xác định một phạm vi bao gồm:

SELECT * FROM address WHERE street_number BETWEEN 4000 AND 4999;

Tại đây, chúng tôi có thể hiển thị bất kỳ customer nào các mục nhập có số an sinh xã hội không dài 9 chữ số. Chúng tôi sử dụng LENGTH() toán tử để lấy số chữ số trong trường và <> để kiểm tra sự bất bình đẳng:

SELECT * FROM customer WHERE LENGTH(SSN) <> 9;



Sử dụng GROUP BY mệnh đề tóm tắt nhiều bản ghi

GROUP BY mệnh đề là một cách rất phổ biến khác để lọc kết quả bằng cách biểu diễn nhiều kết quả với một hàng duy nhất. Cú pháp cơ bản của GROUP BY mệnh đề giống như sau:

SELECT <columns> FROM some_table GROUP BY <columns_to_group>

Khi một GROUP BY mệnh đề được thêm vào một câu lệnh, nó yêu cầu PostgreSQL hiển thị một hàng cho mỗi giá trị duy nhất cho cột hoặc các cột đã cho. Điều này có một số ý nghĩa quan trọng.

Kể từ GROUP BY mệnh đề là một cách biểu diễn nhiều hàng dưới dạng một hàng duy nhất, PostgreSQL chỉ có thể thực hiện truy vấn nếu nó có thể tính toán một giá trị cho mỗi cột mà nó có nhiệm vụ hiển thị. Điều này có nghĩa là mỗi cột được xác định bởi SELECT một phần của câu lệnh phải là:

  • được đưa vào GROUP BY để đảm bảo rằng mỗi hàng có một giá trị duy nhất
  • tóm tắt để tóm tắt tất cả các hàng trong mỗi nhóm

Thực tế mà nói, điều này có nghĩa là bất kỳ cột nào trong SELECT danh sách không có trong GROUP BY mệnh đề phải sử dụng một hàm tổng hợp để tạo ra một kết quả duy nhất cho cột cho mỗi nhóm.


Ví dụ sử dụng GROUP BY

Đối với các ví dụ trong phần này, giả sử rằng chúng ta có một bảng được gọi là pet mà chúng tôi đã xác định và điền như vậy:

CREATE TABLE pet (    id SERIAL PRIMARY KEY,    type TEXT,    name TEXT,    color TEXT,    age INT);INSERT INTO pet (type, name, color, age) VALUES('dog', 'Spot', 'brown', 3),('dog', 'Rover', 'black', 7),('dog', 'Sally', 'brown', 1),('cat', 'Sabrina', 'black', 8),('cat', 'Felix', 'white', 4),('cat', 'Simon', 'orange', 8),('rabbit', 'Buttons', 'grey', 4),('rabbit', 'Bunny', 'brown', 8),('rabbit', 'Briony', 'brown', 6);

Cách sử dụng GROUP BY đơn giản nhất là hiển thị phạm vi giá trị duy nhất cho một cột. Để làm như vậy, hãy sử dụng cùng một cột trong SELECTGROUP BY . Tại đây, chúng ta thấy tất cả các màu được sử dụng trong bảng:

SELECT color FROM pet GROUP BY color;
 color-------- black grey brown white orange(5 rows)

Khi bạn di chuyển ra ngoài một cột duy nhất trong SELECT danh sách cột, bạn phải thêm các cột vào GROUP BY mệnh đề hoặc sử dụng một hàm tổng hợp để tạo ra một giá trị duy nhất cho nhóm hàng đang được biểu diễn.

Ở đây, chúng tôi thêm type vào GROUP BY , nghĩa là mỗi hàng sẽ đại diện cho sự kết hợp duy nhất của typecolor các giá trị. Chúng tôi cũng thêm age , được tóm tắt bởi avg() hàm để tìm tuổi trung bình của mỗi nhóm:

SELECT type, color, avg(age) AS average_age FROM pet GROUP BY type, color;
loại
  type  | color  |     average_age--------+--------+-------------------- rabbit | brown  | 7.0000000000000000 cat    | black  | 8.0000000000000000 rabbit | grey   | 4.0000000000000000 dog    | black  | 7.0000000000000000 dog    | brown  | 2.0000000000000000 cat    | orange | 8.0000000000000000 cat    | white  | 4.0000000000000000(7 rows)

Các hàm tổng hợp cũng hoạt động tốt với một cột trong GROUP BY mệnh đề. Ở đây, chúng tôi tìm thấy tuổi trung bình của từng loại động vật:

SELECT type, avg(age) AS average_age FROM PET GROUP BY type;
loại
  type  |     average_age--------+-------------------- rabbit | 6.0000000000000000 dog    | 3.6666666666666667 cat    | 6.6666666666666667(3 rows)

Nếu chúng ta muốn hiển thị con cũ nhất của từng loại động vật, thay vào đó chúng ta có thể sử dụng max() hàm trên age cột. GROUP BY mệnh đề thu gọn kết quả thành các hàng giống như trước đây, nhưng hàm mới sẽ thay đổi kết quả trong cột khác:

SELECT type, max(age) AS oldest FROM pet GROUP BY type;
loại
  type  | oldest--------+------- rabbit |     8 dog    |     7 cat    |     8(3 rows)



Sử dụng HAVING mệnh đề lọc các nhóm bản ghi

GROUP BY mệnh đề là một cách để tóm tắt dữ liệu bằng cách thu gọn nhiều bản ghi thành một hàng đại diện duy nhất. Nhưng nếu bạn muốn thu hẹp các nhóm này dựa trên các yếu tố bổ sung thì sao?

HAVING mệnh đề là một bổ ngữ cho GROUP BY cho phép bạn chỉ định các điều kiện mà mỗi nhóm phải đáp ứng để được đưa vào kết quả.

Cú pháp chung trông giống như sau:

SELECT <columns> FROM some_table GROUP BY <columns_to_group> HAVING <condition>

Thao tác này rất giống với WHERE mệnh đề, với sự khác biệt là WHERE lọc các bản ghi đơn lẻ và HAVING lọc các nhóm bản ghi.


Ví dụ sử dụng HAVING

Sử dụng cùng một bảng mà chúng tôi đã giới thiệu trong phần trước, chúng tôi có thể chứng minh cách HAVING mệnh đề hoạt động.

Ở đây, chúng tôi nhóm các hàng của pet bảng theo các giá trị duy nhất trong loại address , tìm giá trị nhỏ nhất của age cũng. HAVING sau đó, mệnh đề lọc kết quả để loại bỏ bất kỳ nhóm nào có độ tuổi không lớn hơn 1:

SELECT type, min(age) AS youngest FROM pet GROUP BY type HAVING min(age) > 1;
loại
  type  | youngest--------+---------- rabbit |        4 cat    |        4(2 rows)

Trong ví dụ này, chúng tôi nhóm các hàng trong pet bởi màu sắc của chúng. Sau đó, chúng tôi lọc các nhóm chỉ đại diện cho một hàng duy nhất. Kết quả cho chúng ta thấy mọi màu xuất hiện nhiều lần:

SELECT color FROM pet GROUP BY color HAVING count(color) > 1;
 color------- black brown(2 rows)

Chúng tôi có thể thực hiện một truy vấn tương tự để nhận các kết hợp của typecolor mà chỉ một loài động vật duy nhất có:

SELECT type, color FROM pet GROUP BY type, color HAVING count(color) = 1;
loại
  type  | color--------+-------- cat    | black rabbit | grey dog    | black cat    | orange cat    | white(5 rows)



Sử dụng LIMIT mệnh đề đặt số lượng bản ghi tối đa

LIMIT mệnh đề cung cấp một cách tiếp cận khác để phân tích các bản ghi mà truy vấn của bạn trả về. Thay vì loại bỏ các hàng dữ liệu dựa trên tiêu chí trong chính hàng đó, LIMIT mệnh đề đặt số lượng bản ghi tối đa được trả về bởi một truy vấn.

Cú pháp cơ bản của LIMIT trông như thế này:

SELECT * FROM my_table LIMIT <num_rows> [OFFSET <num_rows_to_skip>];

Đây, <num_rows> cho biết số hàng tối đa để hiển thị từ truy vấn được thực thi. Điều này thường được sử dụng cùng với ORDER BY mệnh đề để nhận các hàng có giá trị lớn nhất trong một cột nhất định. Ví dụ:để đạt được năm điểm cao nhất trong một bài kiểm tra, người dùng có thể ORDER BY một score và sau đó là LIMIT kết quả là 5.

Trong khi LIMIT đếm từ đầu kết quả theo mặc định, OFFSET tùy chọn từ khóa có thể được sử dụng để bù đắp vị trí bắt đầu mà nó sử dụng. Trên thực tế, điều này cho phép bạn phân trang thông qua các kết quả bằng cách hiển thị số lượng kết quả được xác định bởi LIMIT và sau đó thêm LIMIT số cho OFFSET để truy xuất trang sau.


Ví dụ sử dụng LIMIT

Chúng tôi sẽ sử dụng pet bảng từ trước cho các ví dụ trong phần này.

Như đã đề cập ở trên, LIMIT thường được kết hợp với ORDER BY mệnh đề để xác định rõ ràng thứ tự của các hàng trước khi cắt số thích hợp. Ở đây, chúng tôi sắp xếp pet mục nhập theo age của chúng , từ lớn tuổi nhất đến trẻ tuổi nhất. Sau đó, chúng tôi sử dụng LIMIT để hiển thị 5 động vật cổ nhất hàng đầu:

SELECT * FROM pet ORDER BY age DESC LIMIT 5;
loại
  type  |  name   | color  | age | id--------+---------+--------+-----+---- cat    | Simon   | orange |   8 |  6 cat    | Sabrina | black  |   8 |  4 rabbit | Bunny   | brown  |   8 |  8 dog    | Rover   | black  |   7 |  2 rabbit | Briany  | brown  |   6 |  9(5 rows)

Không có ORDER BY mệnh đề, LIMIT sẽ thực hiện các lựa chọn theo cách hoàn toàn có thể dự đoán được. Kết quả trả về có thể được thực hiện theo thứ tự của các mục trong bảng hoặc bởi các chỉ mục. Đây không phải lúc nào cũng là một điều xấu.

Nếu chúng tôi cần một bản ghi cho bất kỳ dog nào trong bảng, chúng ta có thể tạo một truy vấn như thế này. Hãy nhớ rằng mặc dù kết quả có thể khó dự đoán, nhưng đây không phải là lựa chọn ngẫu nhiên và không nên được sử dụng như vậy:

SELECT * FROM pet WHERE type = 'dog' LIMIT 1;
loại
 type | name | color | age | id------+------+-------+-----+---- dog  | Spot | brown |   3 |  1(1 row)

Chúng ta có thể sử dụng OFFSET mệnh đề phân trang thông qua kết quả. Chúng tôi bao gồm một ORDER BY mệnh đề để xác định một thứ tự cụ thể cho các kết quả.

Đối với truy vấn đầu tiên, chúng tôi giới hạn kết quả mà không chỉ định OFFSET để nhận được 3 bài dự thi trẻ nhất đầu tiên:

SELECT * FROM pet ORDER BY age LIMIT 3;
loại
 type | name  | color | age | id------+-------+-------+-----+---- dog  | Sally | brown |   1 |  3 dog  | Spot  | brown |   3 |  1 cat  | Felix | white |   4 |  5(3 rows)

Để có 3 người trẻ nhất tiếp theo, chúng ta có thể thêm số được xác định trong LIMIT vào OFFSET để bỏ qua kết quả mà chúng tôi đã truy xuất:

SELECT * FROM pet ORDER BY age LIMIT 3 OFFSET 3;
loại
  type  |  name   | color | age | id --------+---------+-------+-----+---- rabbit | Buttons | grey  |   4 |  7 rabbit | Briany  | brown |   6 |  9 dog    | Rover   | black |   7 |  2(3 rows)

Nếu chúng ta thêm LIMIT vào OFFSET một lần nữa, chúng ta sẽ nhận được 3 kết quả tiếp theo:

SELECT * FROM pet ORDER BY age LIMIT 3 OFFSET 6;
loại
  type  |  name   | color  | age | id--------+---------+--------+-----+---- cat    | Simon   | orange |   8 |  6 rabbit | Bunny   | brown  |   8 |  8 cat    | Sabrina | black  |   8 |  4(3 rows)

Điều này cho phép chúng tôi truy xuất các hàng dữ liệu từ một truy vấn theo các phần có thể quản lý được.




Kết luận

Có nhiều cách để lọc và hạn chế kết quả bạn nhận được từ các truy vấn. Các mệnh đề như WHEREHAVING đánh giá các hàng hoặc nhóm hàng tiềm năng để xem liệu chúng có thỏa mãn các tiêu chí nhất định hay không. GROUP BY mệnh đề giúp bạn tóm tắt dữ liệu bằng cách nhóm các bản ghi có chung một hoặc nhiều giá trị cột với nhau. LIMIT mệnh đề cung cấp cho người dùng khả năng đặt mức tối đa cố định về số lượng bản ghi cần truy xuất.

Học cách áp dụng các mệnh đề này, riêng lẻ hoặc kết hợp, sẽ cho phép bạn trích xuất dữ liệu cụ thể từ các tập dữ liệu lớn. Công cụ sửa đổi và bộ lọc truy vấn rất cần thiết để biến dữ liệu tồn tại trong PostgreSQL thành các câu trả lời hữu ích.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tôi có thể yêu cầu Postgresql bỏ qua lỗi trong giao dịch không

  2. Làm cách nào để sử dụng dữ liệu mùa xuân jpa để truy vấn cột jsonb?

  3. An toàn chuỗi postgresql cho các bảng tạm thời

  4. Lệnh trả về hàng trong SQL

  5. LỖI:không thể thống kê tệp XX.csv:Lỗi không xác định