PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Cara memfilter hasil kueri di PostgreSQL


Pengantar

Untuk bekerja dengan data dalam database, Anda harus dapat mengambil dan menargetkan catatan tertentu secara efektif. Dengan menggunakan klausa pemfilteran dalam kueri, Anda dapat menambahkan kriteria khusus untuk mengembalikan hanya rekaman yang paling relevan.

Dalam panduan ini, kita akan melihat beberapa operasi penyaringan paling umum yang tersedia dalam PostgreSQL dan mendemonstrasikan cara menggunakannya untuk mempersempit fokus pernyataan Anda. Kami akan menunjukkan cara menguji karakteristik dalam catatan individual dengan WHERE klausa, cara mengelompokkan catatan untuk meringkas informasi dengan GROUP BY , cara memfilter grup record dengan HAVING subklausa, dan cara menyetel jumlah maksimum baris yang dikembalikan dengan LIMIT klausa.



Menggunakan WHERE klausa untuk menentukan kriteria kecocokan

Salah satu cara paling umum dan berguna secara luas untuk menunjukkan persyaratan kueri Anda adalah WHERE ayat. WHERE klausa memungkinkan Anda menentukan kriteria pencarian aktual untuk pernyataan kueri dengan menentukan kondisi yang harus benar untuk semua record yang cocok.

WHERE klausa bekerja dengan mendefinisikan ekspresi boolean yang diperiksa terhadap setiap baris kandidat data. Jika hasil ekspresi salah, baris akan dihapus dari hasil dan tidak akan dikembalikan atau dilanjutkan ke tahap pemrosesan berikutnya. Jika hasil ekspresi benar, maka memenuhi kriteria pencarian dan akan melanjutkan untuk pemrosesan lebih lanjut sebagai baris kandidat.

Sintaks dasar dari WHERE klausanya seperti ini:

SELECT * FROM my_table WHERE <condition>;

<condition> bisa apa saja yang menghasilkan nilai boolean. Di PostgreSQL, nilai boolean adalah salah satu dari TRUE , FALSE , atau NULL .

Kondisi sering dibentuk menggunakan satu atau lebih operator berikut:

  • = :sama dengan
  • > :lebih besar dari
  • < :kurang dari
  • >= :lebih besar dari atau sama dengan
  • <= :kurang dari atau sama dengan
  • < atau != :tidak sama
  • AND :operator logika "dan" — menggabungkan dua kondisi dan mengembalikan TRUE jika kedua kondisi TRUE
  • OR :operator "atau" logis — menggabungkan dua kondisi dan mengembalikan TRUE jika setidaknya salah satu kondisinya TRUE
  • IN :nilai terdapat dalam daftar, rangkaian, atau rentang yang mengikuti
  • BETWEEN :nilai terkandung dalam rentang nilai minimum dan maksimum yang mengikuti, inklusif
  • IS NULL :cocok jika nilainya NULL
  • NOT :meniadakan nilai boolean yang mengikuti
  • EXISTS :kueri berikut berisi hasil
  • LIKE :cocok dengan suatu pola (menggunakan karakter pengganti % untuk mencocokkan 0 karakter atau lebih dan _ untuk mencocokkan satu karakter)
  • ILIKE :cocok dengan suatu pola (menggunakan karakter pengganti % untuk mencocokkan 0 karakter atau lebih dan _ untuk mencocokkan satu karakter), tidak peka huruf besar/kecil
  • SIMILAR TO :cocok dengan pola menggunakan dialek ekspresi reguler SQL
  • ~ :cocok dengan pola menggunakan ekspresi reguler POSIX, peka huruf besar/kecil
  • ~* :cocok dengan pola menggunakan ekspresi reguler POSIX, tidak peka huruf besar/kecil
  • !~ :tidak cocok dengan pola yang menggunakan ekspresi reguler POSIX, peka huruf besar/kecil
  • !~* :tidak cocok dengan pola yang menggunakan ekspresi reguler POSIX, tidak peka huruf besar/kecil

Meskipun daftar di atas mewakili beberapa konstruksi pengujian yang paling umum, ada banyak operator lain yang menghasilkan hasil boolean yang dapat digunakan bersama dengan WHERE klausa.


Contoh menggunakan WHERE

Salah satu pemeriksaan yang paling umum dan langsung adalah untuk kesetaraan, menggunakan = operator. Di sini, kami memeriksa apakah setiap baris di customer tabel memiliki last_name nilai sama dengan Smith :

SELECT * FROM customer WHERE last_name = 'Smith';

Kita dapat menambahkan kondisi tambahan untuk membuat ekspresi majemuk menggunakan operator logika. Contoh ini menggunakan AND klausa untuk menambahkan tes tambahan terhadap first_name kolom. Baris yang valid harus memenuhi kedua kondisi yang diberikan:

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

Demikian pula, kita dapat memeriksa apakah salah satu dari serangkaian kondisi terpenuhi. Di sini, kami memeriksa baris dari address tabel untuk melihat apakah zip_code nilainya sama dengan 60626 atau neighborhood kolom sama dengan string "Roger's Park". Kami menggunakan dua tanda kutip tunggal untuk menunjukkan bahwa kutipan tunggal literal harus dicari:

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

IN operator dapat bekerja seperti perbandingan antara sejumlah nilai, dibungkus dalam tanda kurung. Jika ada kecocokan dengan salah satu nilai yang diberikan, ekspresinya adalah TRUE :

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

Di sini, kami memeriksa pola string menggunakan LIKE . % berfungsi sebagai karakter pengganti yang cocok dengan nol atau lebih karakter, jadi "Pete", "Peter", dan string lain apa pun yang dimulai dengan "Pete" akan cocok:

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

Kita bisa melakukan pencarian serupa menggunakan ~* operator untuk memeriksa kecocokan menggunakan ekspresi reguler POSIX tanpa memperhatikan huruf besar/kecil. Dalam hal ini, kami memeriksa apakah nilai last_name dimulai dengan "d" dan berisi substring "on", yang akan cocok dengan nama seperti "Dickson", "Donald", dan "Devon":

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

Kami dapat memeriksa apakah nomor jalan berada dalam 4000 blok alamat menggunakan BETWEEN dan AND operator untuk menentukan rentang inklusif:

SELECT * FROM address WHERE street_number BETWEEN 4000 AND 4999;

Di sini, kami dapat menampilkan customer entri yang memiliki nomor jaminan sosial yang panjangnya tidak 9 digit. Kami menggunakan LENGTH() operator untuk mendapatkan jumlah digit di bidang dan < untuk memeriksa ketidaksetaraan:

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



Menggunakan GROUP BY klausa untuk meringkas beberapa record

GROUP BY klausa adalah cara lain yang sangat umum untuk memfilter hasil dengan mewakili beberapa hasil dengan satu baris. Sintaks dasar GROUP BY klausanya seperti ini:

SELECT <columns> FROM some_table GROUP BY <columns_to_group>

Ketika GROUP BY klausa ditambahkan ke pernyataan, ia memberitahu PostgreSQL untuk menampilkan satu baris untuk setiap nilai unik untuk kolom atau kolom yang diberikan. Ini memiliki beberapa implikasi penting.

Sejak GROUP BY klausa adalah cara untuk mewakili beberapa baris sebagai satu baris, PostgreSQL hanya dapat mengeksekusi kueri jika dapat menghitung nilai untuk setiap kolom yang ditugaskan untuk ditampilkan. Artinya setiap kolom diidentifikasi dengan SELECT bagian dari pernyataan harus:

  • termasuk dalam GROUP BY klausa untuk menjamin bahwa setiap baris memiliki nilai unik
  • disarikan untuk meringkas semua baris dalam setiap grup

Secara praktis, ini berarti bahwa setiap kolom di SELECT daftar tidak termasuk dalam GROUP BY klausa harus menggunakan fungsi agregat untuk menghasilkan satu hasil untuk kolom untuk setiap grup.


Contoh menggunakan GROUP BY

Untuk contoh di bagian ini, misalkan kita memiliki tabel bernama pet yang telah kita definisikan dan isi seperti ini:

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

Penggunaan paling sederhana GROUP BY adalah untuk menampilkan rentang nilai unik untuk satu kolom. Untuk melakukannya, gunakan kolom yang sama di SELECT dan GROUP BY . Di sini, kita melihat semua warna yang digunakan dalam tabel:

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

Saat Anda bergerak melampaui satu kolom di SELECT daftar kolom, Anda harus menambahkan kolom ke GROUP BY klausa atau gunakan fungsi agregat untuk menghasilkan nilai tunggal untuk grup baris yang diwakili.

Di sini, kami menambahkan type ke GROUP BY klausa, artinya setiap baris akan mewakili kombinasi unik dari type dan color nilai-nilai. Kami juga menambahkan age kolom, diringkas oleh avg() fungsi untuk mencari usia rata-rata dari masing-masing kelompok:

SELECT type, color, avg(age) AS average_age FROM pet GROUP BY type, color;
  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)

Fungsi agregat bekerja dengan baik dengan satu kolom di GROUP BY ayat. Di sini, kami menemukan usia rata-rata setiap jenis hewan:

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

Jika kita ingin menampilkan yang tertua dari setiap jenis hewan, kita bisa menggunakan max() fungsi pada age kolom. GROUP BY klausa menciutkan hasil ke dalam baris yang sama seperti sebelumnya, tetapi fungsi baru mengubah hasil di kolom lain:

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



Menggunakan HAVING klausa untuk memfilter grup catatan

GROUP BY klausa adalah cara untuk meringkas data dengan menciutkan beberapa catatan menjadi satu baris perwakilan. Tetapi bagaimana jika Anda ingin mempersempit grup ini berdasarkan faktor tambahan?

Kode HAVING klausa adalah pengubah untuk GROUP BY klausa yang memungkinkan Anda menentukan kondisi yang harus dipenuhi setiap grup untuk disertakan dalam hasil.

Sintaks umumnya terlihat seperti ini:

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

Operasi ini sangat mirip dengan WHERE klausa, dengan perbedaannya adalah WHERE menyaring catatan tunggal dan HAVING menyaring kelompok catatan.


Contoh menggunakan HAVING

Menggunakan tabel yang sama yang kami perkenalkan di bagian terakhir, kami dapat mendemonstrasikan bagaimana HAVING klausa berfungsi.

Di sini, kami mengelompokkan baris pet tabel dengan nilai unik dalam type kolom, mencari nilai minimum age demikian juga. Kode HAVING klausa kemudian memfilter hasil untuk menghapus grup mana pun yang usianya tidak lebih dari 1:

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

Dalam contoh ini, kami mengelompokkan baris dalam pet oleh warna mereka. Kami kemudian memfilter grup yang hanya mewakili satu baris. Hasilnya menunjukkan kepada kita setiap warna yang muncul lebih dari sekali:

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

Kami dapat melakukan kueri serupa untuk mendapatkan kombinasi type dan color yang hanya dimiliki satu hewan:

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



Menggunakan LIMIT klausa untuk mengatur jumlah maksimum record

LIMIT klausa menawarkan pendekatan berbeda untuk mengurangi catatan yang dikembalikan kueri Anda. Daripada menghilangkan baris data berdasarkan kriteria di dalam baris itu sendiri, LIMIT klausa menetapkan jumlah maksimum catatan yang dikembalikan oleh kueri.

Sintaks dasar LIMIT terlihat seperti ini:

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

Di sini, <num_rows> menunjukkan jumlah baris maksimum untuk ditampilkan dari kueri yang dieksekusi. Ini sering digunakan bersama dengan ORDER BY klausa untuk mendapatkan baris dengan nilai paling ekstrim dalam kolom tertentu. Misalnya, untuk mendapatkan lima nilai terbaik dalam ujian, pengguna dapat ORDER BY sebuah score kolom lalu LIMIT hasilnya menjadi 5.

Sementara LIMIT dihitung dari atas hasil secara default, OFFSET opsional kata kunci dapat digunakan untuk mengimbangi posisi awal yang digunakannya. Akibatnya, ini memungkinkan Anda untuk membuat paginasi melalui hasil dengan menampilkan jumlah hasil yang ditentukan oleh LIMIT lalu tambahkan LIMIT nomor ke OFFSET untuk mengambil halaman berikut.


Contoh menggunakan LIMIT

Kami akan menggunakan pet tabel dari sebelumnya untuk contoh di bagian ini.

Seperti disebutkan di atas, LIMIT sering digabungkan dengan ORDER BY klausa untuk secara eksplisit menentukan urutan baris sebelum mengiris nomor yang sesuai. Di sini, kami mengurutkan pet entri sesuai dengan age their , dari tertua ke termuda. Kami kemudian menggunakan LIMIT untuk menampilkan 5 hewan tertua teratas:

SELECT * FROM pet ORDER BY age DESC LIMIT 5;
  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)

Tanpa ORDER BY klausa, LIMIT akan membuat pilihan dengan cara yang sepenuhnya dapat diprediksi. Hasil yang dikembalikan dapat dipengaruhi oleh urutan entri dalam tabel atau oleh indeks. Ini tidak selalu buruk.

Jika kami membutuhkan catatan untuk dog tunggal mana pun di dalam tabel, kita bisa membuat kueri seperti ini. Ingatlah bahwa meskipun hasilnya mungkin sulit diprediksi, ini bukan pilihan acak dan tidak boleh digunakan seperti itu:

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

Kita dapat menggunakan OFFSET klausa untuk membuat halaman melalui hasil. Kami menyertakan ORDER BY klausa untuk menentukan urutan tertentu untuk hasil.

Untuk kueri pertama, kami membatasi hasil tanpa menentukan OFFSET untuk mendapatkan 3 entri termuda pertama:

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

Untuk mendapatkan 3 bungsu berikutnya, kita dapat menambahkan angka yang ditentukan dalam LIMIT ke OFFSET untuk melewati hasil yang telah kami ambil:

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

Jika kita menambahkan LIMIT ke OFFSET lagi, kita akan mendapatkan 3 hasil berikutnya:

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

Ini memungkinkan kami mengambil baris data dari kueri dalam potongan yang dapat dikelola.




Kesimpulan

Ada banyak cara untuk memfilter dan sebaliknya membatasi hasil yang Anda dapatkan dari kueri. Klausa seperti WHERE dan HAVING mengevaluasi baris atau kelompok baris potensial untuk melihat apakah mereka memenuhi kriteria tertentu. GROUP BY klausa membantu Anda meringkas data dengan mengelompokkan rekaman yang memiliki satu atau beberapa nilai kolom yang sama. LIMIT klausa menawarkan kemampuan kepada pengguna untuk menetapkan jumlah maksimum catatan yang akan diambil.

Mempelajari bagaimana klausa ini dapat diterapkan, secara individual atau dalam kombinasi, akan memungkinkan Anda mengekstrak data tertentu dari kumpulan data besar. Pengubah dan filter kueri sangat penting untuk mengubah data yang ada di dalam PostgreSQL menjadi jawaban yang berguna.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Konversi Django RawQuerySet ke Queryset

  2. Performa OLTP sejak PostgreSQL 8.3

  3. Menyortir nilai nol setelah yang lainnya, kecuali spesial

  4. Kesalahan Heroku PostgreSQL GROUP_BY di aplikasi Rails

  5. Saat melakukan PITR, apakah mungkin untuk Menjeda/Melanjutkan di PostgreSQL ?