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

Pertanyaan PostgreSQL Favorit Saya dan Mengapa Itu Penting

Basis data, tabel, normalisasi, dan rencana pencadangan yang solid memungkinkan kami menyimpan dan memelihara data.

Kombinasi praktik terbaik tersebut, pada gilirannya, memungkinkan kami berinteraksi dengan data tersebut. Di dunia yang didorong oleh data saat ini, data sangat berharga. Tidak hanya berharga, data seringkali penting untuk solusi pengguna akhir yang disediakan oleh produk dan layanan. Mengekstrak wawasan, menjawab pertanyaan, dan metrik yang bermakna dari data melalui kueri dan manipulasi data merupakan komponen integral dari SQL secara umum.

PostgreSQL tidak berbeda.

Inti dasar ini sangat penting untuk keberhasilan dalam aspek apa pun yang didorong oleh data.

Di bawah ini, saya menyajikan kombinasi 8 kueri atau jenis kueri berbeda yang menurut saya menarik dan menarik untuk dijelajahi, dipelajari, dipelajari, atau memanipulasi kumpulan data.

Mereka tidak terdaftar dalam urutan kepentingan apa pun.

Sebagian besar mungkin akan menjadi teman lama yang akrab. Mungkin beberapa akan menjadi kenalan baru.

Tabel sampel dan data yang digunakan tidak sepenting konstruksi sebenarnya dari kueri itu sendiri dan apa yang dikembalikan, ditawarkan, atau disediakan oleh setiap kueri. Banyak dari mereka adalah tiruan dan diturunkan untuk tujuan demonstrasi dan tidak boleh diartikan secara harfiah dalam nilai-nilai mereka.

1. Gabung kiri, perhatikan nol di kanan...

Misalkan dalam contoh ini, kita menjalankan penjualan selama dua bulan dan mendapatkan total dari keduanya digabungkan.

Namun, untuk beberapa alasan, bulan kedua tidak menarik dan kami ingin menargetkan hari apa bulan pertama mulai berkurang.

Penjualan ini direpresentasikan sebagai tabel pembayaran dan fake_month untuk demonstrasi ini.

Untuk diperhatikan:

  • Kami hanya akan memeriksa total yang lebih besar dari 2000.
  • Kami akan membatasi keluaran hanya 10 baris.

Untuk memulai, kami memiliki Common Table Expression (CTE) 'menghasilkan ' tabel fake_month untuk kami, dan kueri yang mengikuti.

dvdrental=> WITH fake_month AS(
SELECT setup::date
FROM generate_series('2007-02-01', '2007-02-28', INTERVAL '1 day') AS setup
)
SELECT date_part('day', p.payment_date)::INT AS legit,
SUM(p.amount),
date_part('day', fk.setup)::INT AS fake
FROM payment AS p
LEFT JOIN fake_month AS fk
ON date_part('day', fk.setup)::INT = date_part('day', p.payment_date)::INT
GROUP BY legit, fake
HAVING SUM(p.amount) > 2000
LIMIT 10;
legit | sum | fake
-------+---------+------
1 | 2808.24 | 1
2 | 2550.05 | 2
6 | 2077.14 | 6
8 | 2227.84 | 8
9 | 2067.86 | 9
17 | 3630.33 | 17
18 | 3977.74 | 18
19 | 3908.59 | 19
20 | 3888.98 | 20
21 | 3786.14 | 21
(10 rows)

Sepertinya kedua bulan berkontribusi di sana. Jadi apakah ini terpecahkan?

Sebelum kita menganggap ini terpecahkan, mari kita kunjungi klausa ORDER BY.

Tentu saja, Anda dapat MEMESAN MELALUI ASC atau DESC.

Namun, Anda juga dapat ORDER BY NULLS terlebih dahulu atau terakhir dan itu sedikit mengubah segalanya.

Mari kita tulis ulang kueri ini dan gunakan ORDER BY NULLS terlebih dahulu di kolom yang sah.

Untuk singkatnya, saya akan menghapus CTE dari output, ketahuilah bahwa itu masih ada dan sedang digunakan.

SELECT date_part('day', p.payment_date)::INT AS legit,
SUM(p.amount),
date_part('day', fk.setup)::INT AS fake
FROM payment AS p
LEFT JOIN fake_month AS fk
ON date_part('day', fk.setup)::INT = date_part('day', p.payment_date)::INT
GROUP BY legit, fake
HAVING SUM(p.amount) > 2000
ORDER BY legit NULLS first
LIMIT 10;
legit | sum | fake
-------+---------+------
1 | 2808.24 | 1
2 | 2550.05 | 2
6 | 2077.14 | 6
8 | 2227.84 | 8
9 | 2067.86 | 9
17 | 3630.33 | 17
18 | 3977.74 | 18
19 | 3908.59 | 19
20 | 3888.98 | 20
21 | 3786.14 | 21
(10 rows)

Tidak ada perbedaan sama sekali.

Bagaimana jika kita ORDER BY NULLS dulu di kolom palsu? Yang di kanan sisi GABUNG?

Mari kita lihat.

SELECT date_part('day', p.payment_date)::INT AS legit,
SUM(p.amount),
date_part('day', fk.setup)::INT AS fake
FROM payment AS p
LEFT JOIN fake_month AS fk
ON date_part('day', fk.setup)::INT = date_part('day', p.payment_date)::INT
GROUP BY legit, fake
HAVING SUM(p.amount) > 2000
ORDER BY fake NULLS first
LIMIT 10;
legit | sum | fake
-------+---------+------
29 | 2717.60 |
30 | 5723.89 |
1 | 2808.24 | 1
2 | 2550.05 | 2
6 | 2077.14 | 6
8 | 2227.84 | 8
9 | 2067.86 | 9
17 | 3630.33 | 17
18 | 3977.74 | 18
19 | 3908.59 | 19
(10 rows)

Sekarang kita menuju suatu tempat. Kita bisa lihat pada hari ke 29 &30, kolom palsu telah dipesan dari atas set hasil.

Karena ORDER BY NULLS palsu dulu.

Ini memecahkan pertanyaan kami, sampai hari apa 'penjualan 2' mengendur.

Apakah Anda bertanya-tanya...

"Bisakah kita memfilter dengan WHERE palsu IS NULL? "

Seperti ini:

SELECT date_part('day', p.payment_date)::INT AS legit,
SUM(p.amount),
date_part('day', fk.setup)::INT AS fake
FROM payment AS p
LEFT JOIN fake_month AS fk
ON date_part('day', fk.setup)::INT = date_part('day', p.payment_date)::INT
WHERE date_part('day', fk.setup) IS NULL
GROUP BY legit, fake
HAVING SUM(p.amount) > 2000
LIMIT 10;
legit | sum | fake
-------+---------+------
29 | 2717.60 |
30 | 5723.89 |
(2 rows)

Ya itu berhasil. Jadi mengapa tidak menggunakan kueri itu saja? Mengapa itu penting?

Saya merasa menggunakan LEFT JOIN dan ORDER BY NULLS terlebih dahulu untuk tabel di sisi kanan JOIN, adalah cara yang bagus untuk menjelajahi tabel dan kumpulan data yang tidak dikenal.

Dengan mengonfirmasi data apa, jika ada, yang ‘hilang ' di sisi itu dari kondisi join terlebih dahulu; meningkatkan kejelasan dan kesadaran, memungkinkan Anda untuk memfilter hasil yang ditetapkan dengan klausa WHERE IS NULL, menyelesaikan semuanya.

Tentu saja, pemahaman tentang tabel dan kumpulan data berpotensi menghilangkan kebutuhan LEFT JOIN yang disajikan di sini.

Ini adalah kueri yang layak bagi siapa saja yang menggunakan PostgreSQL untuk setidaknya mencoba, selama penjelajahan.

2. Penggabungan String

Penggabungan, penggabungan atau penambahan dua string, menyediakan opsi presentasi untuk kumpulan hasil. Banyak 'hal ' dapat digabungkan.

Namun, seperti yang dicatat dalam dokumentasi, operator rangkaian string ('||') menerima input non-string, selama salah satunya adalah string.

Mari kita lihat beberapa contoh dengan pertanyaan di bawah ini:

postgres=> SELECT 2||' times'||' 2 equals: '|| 2*2;
?column?
---------------------
2 times 2 equals: 4
(1 row)

Kita bisa lihat, angka dan string semua bisa digabungkan menjadi satu seperti yang disebutkan di atas.

'||' operator hanyalah salah satu dari yang tersedia di PostgreSQL.

Fungsi concat() menerima beberapa argumen, menggabungkan semuanya saat kembali.

Berikut adalah contoh dari fungsi tersebut dalam tindakan:

postgres=> SELECT concat('Josh ','Otwell') AS first_name;
first_name
-------------
Josh Otwell
(1 row)

Kami dapat menyampaikan lebih dari dua argumen jika diinginkan:

postgres=> SELECT concat('Josh',' ','Otwell') AS first_name;
first_name
-------------
Josh Otwell
(1 row)

Mari kita perhatikan sesuatu dengan cepat dengan contoh berikut ini:

postgres=> SELECT CONCAT('Josh',NULL,'Otwell') AS first_name;
first_name
------------
JoshOtwell
(1 row)
postgres=> SELECT 'Josh '||NULL||'Otwell' AS first_name;
first_name
------------
(1 row)
postgres=> SELECT NULL||'Josh '||'Otwell' AS first_name;
first_name
------------
(1 row)
postgres=> SELECT CONCAT(NULL,'Josh','Otwell') AS first_name;
first_name
------------
JoshOtwell
(1 row)

Perhatikan bahwa fungsi concat() mengabaikan NULL di mana pun ditempatkan dalam daftar parameter, sedangkan operator rangkaian string tidak.

NULL dikembalikan jika ada di mana saja dalam string untuk digabungkan.

Sadarilah itu.

Alih-alih memasukkan secara manual ke dalam string yang akan digabungkan, PostgreSQL juga menyertakan fungsi concat_ws() yang menerima pemisah string sebagai parameter pertama.

Kami akan mengunjunginya dengan pertanyaan berikut:

postgres=> SELECT concat_ws('-',333,454,1919) AS cell_num;
cell_num
--------------
333-454-1919
(1 row)
postgres=> SELECT concat_ws(' ','Josh','Otwell') AS first_name;
first_name
-------------
Josh Otwell
(1 row)

concat_ws() menerima angka atau string sebagai argumen dan seperti yang dinyatakan di atas, menggunakan argumen pertama sebagai pemisah.

Bagaimana concat_ws() memperlakukan NULL?

postgres=> SELECT concat_ws('-',333,NULL,1919) AS cell_num;
cell_num
----------
333-1919
(1 row)
postgres=> SELECT concat_ws(NULL,333,454,1919) AS cell_num;
cell_num
----------
(1 row)

NULL diabaikan kecuali itu adalah argumen pemisah yang diberikan kepada concat_ws().

Kemudian, semua argumen diabaikan dan NULL dikembalikan sebagai gantinya.

Penggabungannya keren...

Sekarang setelah kita memiliki gagasan tentang cara kerja penggabungan, mari kita lihat beberapa contohnya.

Kembali ke database persewaan DVD tiruan

Misalkan kita perlu menyusun daftar nama depan dan belakang pelanggan, bersama dengan alamat email mereka untuk mengirimkan memo untuk memperbarui akun mereka.

Saya akan membatasi output menjadi hanya 10 baris demi singkatnya, tetapi masih mendemonstrasikan || operator.

dvdrental=> SELECT first_name||' '||last_name||'''s email address is: '||email AS name_and_email
FROM customer
LIMIT 10;
name_and_email
--------------------------------------------------------------------------
Jared Ely's email address is: [email protected]
Mary Smith's email address is: [email protected]
Patricia Johnson's email address is: [email protected]
Linda Williams's email address is: [email protected]
Barbara Jones's email address is: [email protected]
Elizabeth Brown's email address is: [email protected]
Jennifer Davis's email address is: [email protected]
Maria Miller's email address is: [email protected]
Susan Wilson's email address is: [email protected]
Margaret Moore's email address is: [email protected]
(10 rows)

Perhatikan bahwa kami harus menghindari tanda kutip tunggal yang digunakan dengan apostrof s, menggunakan tanda kutip tunggal tambahan untuk menunjukkan kepemilikan alamat email untuk setiap pelanggan.

Mengapa Anda harus tahu?

Ada kalanya menggabungkan data memberi Anda wawasan dan pemahaman yang lebih baik tentang kumpulan data yang sedang Anda kerjakan. Bersama dengan opsi pelaporan, menggabungkan kumpulan data bersama dengan orang lain berpotensi membuatnya (data) lebih mudah dibaca dan dicerna.

3. Memasok daftar nilai IN Dengan

Subquery

Subquery memiliki banyak kegunaan yang kuat. Dari semua itu, memberikan daftar nilai IN untuk memeriksa keanggotaan adalah hal yang umum.

Berikut ini penggunaan cepat.

Misalkan kita memiliki tabel pelanggan dan pembayaran di toko persewaan DVD tiruan dan ingin memberi penghargaan kepada lima pelanggan dengan pembelanjaan tertinggi yang menyewa film selama hari 10 - 13 April.

Bayangkan itu adalah periode target khusus. Jadi, jika pelanggan membelanjakan lebih dari $30, kami ingin mengakuinya.

Ingatlah, ada opsi lain yang tersedia untuk menyelesaikan jenis pertanyaan ini (yaitu, menggabungkan, menangkap hasil dari beberapa pilihan, dll...), namun, sub-kueri juga dapat menanganinya.

Kami akan mulai dengan seluruh shebang di sini. Kueri lengkap ini mengembalikan semua yang kami inginkan untuk pertanyaan khusus ini.

dvdrental=> SELECT first_name, last_name, email
FROM customer
WHERE customer_id IN (
SELECT customer_id FROM (
SELECT DISTINCT customer_id, SUM(amount)
FROM payment
WHERE extract(month from payment_date) = 4
AND extract(day from payment_date) BETWEEN 10 AND 13
GROUP BY customer_id
HAVING SUM(amount) > 30
ORDER BY SUM(amount) DESC
LIMIT 5) AS top_five);

Contoh ini sebenarnya berisi subquery bersarang, salah satunya adalah Derived Table.

Mari kita mulai dengan menelusuri subquery terdalam, Tabel Turunan itu.

Subquery ini adalah pernyataan SELECT mandiri, mengembalikan customer_id dan SUM() pada kolom jumlah.

Hanya pelanggan yang memenuhi kriteria yang diperiksa oleh klausa WHERE dan HAVING yang lolos, yang selanjutnya dipersempit dengan LIMIT 5;

Mengapa subquery berikutnya yang Anda tanyakan?

Bisakah kita tidak menggunakan bagian WHERE customer_id IN dari SELECT terluar di sini?

Mari kita lihat dengan pendekatan langsung.

Saya akan menghapus AS top_five dari subquery dan mencoba kueri terluar dengannya sekarang:

dvdrental=> SELECT first_name, last_name, email
FROM customer
WHERE customer_id IN
(SELECT DISTINCT customer_id, SUM(amount)
FROM payment
WHERE extract(month from payment_date) = 4
AND extract(day from payment_date) BETWEEN 10 AND 13
GROUP BY customer_id
HAVING SUM(amount) > 30
ORDER BY SUM(amount) DESC
LIMIT 5);
ERROR: subquery has too many columns
LINE 3: WHERE customer_id IN (

Di sini, keanggotaan IN sedang diuji dengan hanya kolom customer_id, namun Tabel Turunan mengembalikan dua kolom dan PostgreSQL memberi tahu kami.

Salah satu solusi adalah dengan menggunakan subquery lain. Memilih hanya customer_id dari kumpulan hasil Tabel Turunan, membuat subkueri bersarang dalam berikutnya.

Sekarang predikat IN berisi beberapa baris dari nilai satu kolom untuk memeriksa keanggotaan terhadap klausa WHERE untuk customer_id untuk membuat hasil akhir ditetapkan.

Mengapa itu penting?

Memanfaatkan subquery dengan cara ini sangat kuat karena fakta jumlah nilai yang berpotensi dapat diuji dengan predikat IN().

Bayangkan jika ada 100? Atau lebih?

'Hard-coding ' semuanya dalam daftar IN() dapat menjadi masalah dan rawan kesalahan seiring dengan meningkatnya volume nilai.

4. generate_series()

Fungsi pengembalian set ini, berguna dan sangat menyenangkan untuk digunakan dan dijelajahi. Saya telah menggunakan generate_series() dalam contoh di atas, tetapi layak untuk dibicarakan sendiri. Lebih fokus pada fungsi dan kapabilitas.

Saya menemukan generate_series() berguna untuk kueri komparatif di mana beberapa, atau semua data hilang.

Atau hanya sebagian data yang tersedia pada saat saya menjelajah. Salah satu kegunaan praktis adalah mengisi tabel dengan 'data dummy '.

Untuk memulai, kita akan membuat tabel sederhana:

trial=> CREATE TABLE tbl_1(
trial(> tb_id SERIAL PRIMARY KEY,
trial(> some_day DATE,
trial(> an_amt NUMERIC(4,2));
CREATE TABLE

Kemudian gunakan generate_series() sebagai VALUES untuk pernyataan INSERT kami:

trial=> INSERT INTO tbl_1(some_day, an_amt)
VALUES(
generate_series('2018-04-01','2018-04-15',INTERVAL '1 day'),
generate_series(2.43, 34.20, 1.03));
INSERT 0 31

Kemudian buat tabel kedua

trial=> CREATE TABLE tbl_2(
tb2_id SERIAL PRIMARY KEY,
some_day2 DATE,
an_amt2 NUMERIC(4,2));
CREATE TABLE

Juga, isi menggunakan generate_series() dalam pernyataan INSERT:

trial=> INSERT INTO tbl_2(some_day2, an_amt2)
VALUES(
generate_series('2018-05-16','2018-05-31',INTERVAL '1 day'),
generate_series(15.43, 31., 1.03));
INSERT 0 16

Mengapa itu penting?

Untuk mengulangi, generate_series() sangat berguna untuk membuat data tiruan atau latihan.

Saya telah menemukan meniru rentang bulan atau hari untuk perbandingan luar biasa dengan generate_series(). Lihat bagian 1 dan CTE di sana, yang menunjukkan penggunaan ini.

Membuat satu set data lengkap dengan generate_series() dan menggunakannya untuk membandingkan dengan data yang disimpan untuk menentukan apakah ada data yang hilang juga memiliki nilai yang bagus.

5. Kueri Dengan COUNT() Fungsi Agregat.

Fungsi agregat yang sederhana namun efektif ini harus ada di gudang senjata siapa pun. Terutama saat menjelajahi tabel atau kumpulan data untuk pertama kalinya.

Maksud saya, apakah Anda benar-benar ingin 'PILIH semuanya ' dari tabel dengan 1 juta baris?

Tentukan dengan COUNT(*) berapa banyak catatan yang ada sebelum Anda memuat.

Mari kita cari tahu berapa baris tabel film di tabel sewa DVD tiruan ini:

dvdrental=> SELECT COUNT(*)
dvdrental-> FROM film;
count
-------
1000
(1 row)

Meskipun tidak seluas 1 juta+ baris, saya yakin Anda melihat manfaatnya.

Untuk mengembalikan jumlah baris tertentu, COUNT(*) dapat difilter dengan klausa WHERE.

Mari kita lihat berapa banyak film yang memiliki peringkat 'G':

dvdrental=> SELECT COUNT(*)
dvdrental-> FROM film
dvdrental-> WHERE rating = 'G';
count
-------
178
(1 row)

Ada bentuk lain dari COUNT() yang harus diperhatikan. COUNT(ekspresi_beberapa) .

Perbedaan di antara mereka adalah:

  • COUNT(*) mengembalikan total semua baris input (termasuk NULLS dan duplikat).
  • COUNT(beberapa_ekspresi ) menghitung jumlah baris input non-NULL.

Saat digunakan bersama dengan kata kunci DISTINCT, COUNT() akan menghilangkan entri duplikat dan hanya mengembalikan nilai unik.

Mari kita lihat aksinya menggunakan COUNT() dengan DISTINCT untuk menentukan berapa banyak jenis peringkat unik yang ada:

dvdrental=> SELECT COUNT(DISTINCT rating) FROM film;
count
-------
5
(1 row)

Dengan kueri ini, kami mengetahui bahwa ada 5 jenis peringkat.

Mengapa itu penting?

Bergantung pada apa yang sedang dilacak atau ditargetkan, mengetahui berapa banyak sesuatu yang ada bisa menjadi penting. Oleh karena itu, gunakan COUNT(*) atau COUNT(some_expression ) membantu dengan jenis tantangan ini.

Ingat saja COUNT(*) tidak mengabaikan NULL. Semua baris, duplikat, dan nilai NULL yang disertakan, dikembalikan sebagai bagian dari angka akhir.

6. UPDATE beberapa baris dengan ekspresi CASE.

Misalkan kita memiliki tabel ini:

trial=> SELECT * FROM reward_members;
rm_id | expense_amt | member_status
-------+-------------+---------------
1 | 1245.33 | gold
2 | 1300.49 | gold
3 | 900.20 | bronze
4 | 2534.44 | platinum
5 | 600.19 | bronze
6 | 1001.55 | silver
7 | 1097.99 | silver
8 | 3033.33 | platinum
(8 rows)

Kita perlu mengganti nama kolom member_status dan menambahkan 'grup ' ke akhir nama saat ini yang ada untuk setiap record.

Sebagai permulaan, beberapa pernyataan UPDATE individual akan menyelesaikan ini tanpa masalah.

Tapi, begitu juga satu ekspresi CASE.

trial=> UPDATE reward_members
SET member_status = (
CASE member_status
WHEN 'gold' THEN 'gold_group'
WHEN 'bronze' THEN 'bronze_group'
WHEN 'platinum' THEN 'platinum_group'
WHEN 'silver' THEN 'silver_group'
END
)
WHERE member_status IN ('gold', 'bronze','platinum', 'silver');
UPDATE 8

Mari kita query tabel lagi untuk melihat perubahannya:

trial=> SELECT * FROM reward_members;
rm_id | expense_amt | member_status
-------+-------------+----------------
1 | 1245.33 | gold_group
2 | 1300.49 | gold_group
3 | 900.20 | bronze_group
4 | 2534.44 | platinum_group
5 | 600.19 | bronze_group
6 | 1001.55 | silver_group
7 | 1097.99 | silver_group
8 | 3033.33 | platinum_group
(8 rows)

Semua pembaruan berhasil.

Mengapa itu penting?

Anda dapat membayangkan berapa banyak perjalanan pulang pergi yang diperlukan ke server jika beberapa pernyataan UPDATE telah dijalankan. Sebenarnya, hanya 4 untuk contoh ini. Tapi tetap saja, potensi untuk banyak orang selalu ada.

Namun, menggunakan UPDATE dengan ekspresi CASE, kami hanya mengirim satu kueri.

7. SALIN dan \salin

PostgreSQL menyediakan COPY, perintah untuk mengekspor data antara file dan tabel.

Pastikan dan kunjungi tautan yang disediakan untuk melihat banyaknya pilihan yang tersedia dengan SALIN.

Catatan penting tentang COPY. Hak istimewa peran SUPERUSER diperlukan untuk menjalankan perintah ini.

Perintah meta psql \copy adalah alternatif bagi pengguna yang tidak menganggap atribut peran ini. Kami akan segera mengunjungi perintah itu.

Pertama, jalankan perintah COPY untuk mengekspor kolom tertentu ke file CSV di mesin lokal.

Asumsikan kita memiliki hasil kueri ini untuk ekspor:

trial=# SELECT expense_amt, member_status
trial-# FROM reward_members
trial-# WHERE member_status = 'gold_group';
expense_amt | member_status
-------------+---------------
1245.33 | gold_group
1300.49 | gold_group
(2 rows)

Dengan COPY, kita dapat menggunakan pernyataan SELECT untuk menyelesaikan ekspor ini.

trial=# COPY (SELECT expense_amt, member_status
FROM reward_members
WHERE member_status = 'gold_group')
TO '/home/linux_user_here/awards_to_honor.csv'
DELIMITER ','
CSV HEADER;
COPY 2

*Catatan:Sesuai dengan dokumentasi, kueri harus berada dalam tanda kurung.

Sekarang mari kita periksa isi file itu:

$ cat awards_to_honor.csv
expense_amt,member_status
1245.33,gold_group
1300.49,gold_group

Kita dapat melihat baris pertama berisi HEADER (yang merupakan nama kolom) dan kedua baris memiliki data biaya_amt dan status_anggota untuk kedua kolom yang dikembalikan dari filter klausa WHERE.

Peringatan penting lainnya yang saya temukan dari menjalankan perintah COPY di atas.

Pengguna harus memiliki hak istimewa untuk menulis ke file di tingkat OS.

Dalam kasus saya, diperbaiki dengan:

$ sudo chown postgres awards_to_honor.csv

Anda dapat menghindari masalah ini dengan menulis ke file sistem yang dapat diakses oleh pengguna saat ini seperti /tmp (ditampilkan di bawah.)

trial=# COPY (SELECT expense_amt, member_status
FROM reward_members
WHERE member_status = 'gold_group')
TO '/tmp/awards_to_honor.csv'
DELIMITER ','
CSV HEADER;
COPY 2

Namun, salah satu peran pengujian saya tanpa atribut SUPERUSER, mengalami masalah saat menulis ke file /tmp.

Lihat di bawah untuk konfirmasi:

trial=# SET role log_user; -- changing from postgres user to log_user
SET

Sekarang mencoba perintah COPY yang sama, menulis ke folder /tmp

trial=> COPY (SELECT expense_amt, member_status
FROM reward_members
WHERE member_status = 'gold_group')
TO '/tmp/awards_to_honor2.csv'
DELIMITER ','
CSV HEADER;
ERROR: must be superuser to COPY to or from a file
HINT: Anyone can COPY to stdout or from stdin. psql's \copy command also works for anyone.

Mungkin ukuran yang lebih baik, seperti yang disarankan dalam PETUNJUK:, untuk peran tanpa atribut SUPERUSER, adalah psql \copy meta-command.

Mari kita jalankan jenis perintah yang serupa dengan \copy alih-alih menggunakan peran yang sama, tanpa memerlukan atribut SUPERUSER itu.

trial=> \copy (SELECT expense_amt, member_status
FROM reward_members
WHERE member_status = 'silver_group')
TO '/home/linux_user_here/more_awards.csv'
DELIMITER ','
CSV HEADER;
COPY 2

Tidak ada masalah di sana.

Dan isi file,

$ cat more_awards.csv
expense_amt,member_status
1001.55,silver_group
1097.99,silver_group

Juga berfungsi untuk folder /tmp:

trial=> \copy (SELECT expense_amt, member_status
FROM reward_members
WHERE member_status = 'silver_group')
TO '/tmp/more_awards.csv'
DELIMITER ','
CSV HEADER;
COPY 2

Konten yang sama juga ada dalam file tertulis:

trial=> \! cat /tmp/more_awards.csv
expense_amt,member_status
1001.55,silver_group
1097.99,silver_group

Mengapa itu penting?

Mengimpor data ke PostgreSQL melalui file adalah metode unggah massal yang pasti. Meskipun semuanya tidak tercakup dalam entri blog ini, COPY dan \copy keduanya, menawarkan beberapa opsi untuk bekerja dengan format dan ekstensi file yang berbeda.

Dengan cara yang sama, mengekspor data dari tabel, atau kolom tertentu juga mudah ditangani dengan kedua perintah ini.

8. psql \help meta-command

Anda berada dalam sesi baris perintah psql. Penasaran dengan sintaks perintah CREATE INDEX?

Tidak perlu dan membuka browser atau dokumen lain.

Coba ini sebagai gantinya:

trial=> \help CREATE INDEX
Command: CREATE INDEX
Description: define a new index
Syntax:
CREATE [ UNIQUE ] INDEX [ CONCURRENTLY ] [ [ IF NOT EXISTS ] name ] ON table_name [ USING method ]
( { column_name | ( expression ) } [ COLLATE collation ] [ opclass ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ] [, ...] )
[ WITH ( storage_parameter = value [, ... ] ) ]
[ TABLESPACE tablespace_name ]
[ WHERE predicate ]

Untuk mengetahui teks bantuan apa yang tersedia, Anda dapat menjalankan \help sendiri dan mendapatkan daftar opsi yang tersedia.

Saya tidak akan mencantumkan semuanya di sini, ketahuilah bahwa opsi itu tersedia.

Mengapa itu penting?

Fakta bahwa meta-command ini sangat mudah digunakan, kuat, dan nyaman adalah kelebihan yang cukup untuk disebutkan di sini. Ini menghemat banyak waktu yang saya habiskan untuk mencari di seluruh dokumentasi lainnya. Dan tentu saja, sebagai seorang pemula, saya cukup sering menggunakannya!

Kesimpulan

Ini bukan daftar yang lengkap. Atau 'menjadi akhir dari segalanya ' dari kueri dan manipulasi data.

Hanya pendapat saya yang menarik minat saya dan berbicara kepada saya saat saya terus belajar dan tumbuh menjadi peran Pengembang SQL. Saya harap melalui posting blog ini, Anda akan menemukan kasus penggunaan untuk kueri dan perintah di atas, menerapkannya sesuai keinginan Anda.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bagaimana date_trunc() Bekerja di PostgreSQL

  2. Kueri N baris terkait terakhir per baris

  3. postgres pengguna meluncurkan proses yang menggunakan semua CPU 100% penggunaan

  4. Pemantauan Kinerja &Audit PostgreSQL - Sumber Daya Teratas

  5. Gunakan koneksi SSL PostgreSQL dengan sertifikat yang ditandatangani sendiri