Salam untuk semua pecinta SQL!
Di Internet, saya jarang melihat artikel yang mencakup berbagai titik kerja dan seluk beluk yang terkait dengan
pemrosesan data dalam SQL .
Saya suka ketika Anda bisa belajar banyak hal dari satu artikel sekaligus, bahkan secara umum.
Karena itu, saya memutuskan untuk menulis artikel saya yang berisi berbagai tugas dan jawaban dengan penjelasan untuknya.
Cocok untuk mereka yang telah menguasai semua keterampilan dasar dengan baik dan ingin mengembangkan lebih lanjut.
Jawaban yang diberikan cocok untuk
PostgreSQL (
sebagian besar tugas akan cocok untuk DBMS lainnya , tetapi hasil dan solusinya mungkin berbeda. Bahkan menarik ketika ada perbedaan)
Coba jawab sendiri sebelum membuka spoiler.
Ayo pergi!
Saya akan mencoba menandai dengan tanda bintang sesuatu murni untuk PostgreSQL * (tidak ada banyak momen seperti itu)
1. Sedikit tentang operasi numerik
1.1 Apakah permintaan ini dapat dipenuhi? Hasil apa yang akan mereka kembalikan?
Jawaban untuk 1.1A) Jawab: 1
Hanya seluruh bagian yang akan ditampilkan, karena operasi menggunakan bilangan bulat. Ini sering ditemukan dalam bahasa lain.
B) Jawab: permintaan tidak akan dieksekusi .
avg akan memberikan kesalahan sejak itu hanya menerima angka dan interval waktu *
Namun, fungsi min / maks dapat dieksekusi pada data teks (sesuai dengan pengurutan alfabetis dalam basis data).
Terkadang ini berguna ketika Anda setidaknya harus melihat kolom yang tidak tercantum dalam GROUP BY
Atau ketika Anda perlu menerapkan penyortiran alfabet ke angka, di mana '10' <'2'
B) Jawab: SALAH
Mungkin terlihat aneh, tetapi ini dapat diterima , karena ini adalah fitur komputer yang mewakili beberapa angka floating-point, suatu angka dapat berbentuk 7.1 (9)
Saya ingat bagaimana saya pernah menangani permintaan untuk waktu yang lama tanpa menyadarinya.
D) Jawab: 0 . tangkapannya adalah ekspresi dalam tanda kurung akan = 0
SELECT (20 / 25.0) * 25 akan bekerja lebih benar
1.2 Diberikan tabel "
table_2 " (dengan satu kolom "
nilai " (INTEGER)) yang terdiri dari 5 baris berikut:
Hasil apa yang akan mengembalikan kueri:
SELECT (avg(value)*count(*)) - sum(value) FROM table_2;
Opsi jawaban- -4
- 0
- Tidak
- 5
- Ini akan menyebabkan kesalahan karena tidak ditentukan GROUP BY
- Tidak ada yang terdaftar
Jawab 1.2jawaban: 5
Fungsi agregat yang diterapkan pada kolom tertentu mengabaikan NULL , namun hitungan (*) akan menghitung semua baris
5 * 5 - 20
2. Masalah umum
2.1 Dalam kasus apa permintaan dapat mengembalikan tidak semua konten tabel? (
parent_id INTEGER, tabel diisi dengan berbagai data)
SELECT * FROM any_table WHERE parent_id = parent_id;
Bagaimana perilaku permintaan di bawah ini? Data apa yang akan dikeluarkannya?
* PostgreSQL SELECT * FROM any_table WHERE parent_id IS NOT DISTINCT FROM parent_id;
Jawaban untuk 2.1Kueri pertama akan menampilkan semua entri kecuali yang parent_id adalah NULL
Kueri kedua akan menampilkan semua entri tabel. IS DISTINCT FROM secara logika mirip dengan operator ! = Di mana NULL identik dengan NULL
BUKAN MENDAPATKAN DARI logis mengubah ketidaksetaraan menjadi kesetaraan
2.2. Apa yang akan menjadi hasil dari permintaan?
Balas ke 2.2Hasilnya akan menjadi 2 baris dengan nilai 1 dan 2 , UNION akan menghapus semua duplikat dalam pilihan yang dihasilkan , dan tidak hanya antara dua tabel yang digabungkan. Saya perhatikan bahwa ini tidak jelas bagi semua orang.
2.3 Tulis kueri yang menunjukkan tanggal besok.
Jawaban untuk 2.3 SELECT CAST((now()+ INTERVAL '1 DAY') AS DATE)
Tidak semua orang sering bekerja dengan tanggal, tetapi ada baiknya menguasai beberapa minimum
* Solusi Postgres, tapi saya rasa DBMS lain tidak jauh berbeda
Jika bekerja dengan tanggal adalah hal baru bagi Anda, saya sarankan Anda untuk bereksperimen dengan permintaan tersebut
Sebagai contoh:
- ganti HARI dengan (minggu, bulan, tahun, dll.)
- ganti +1 dengan -9000
- ganti DATE dengan TIME
- hapus CAST
- hanya menyisakan SEKARANG ()
dll.
Dan, terinspirasi oleh beberapa hasil, bacalah
MANUAL , semua topik di sana dijelaskan secara rinci
2.4 Pernyataan
UPDATE ,
DELETE ,
INSERT, dan
MERGE dirancang untuk memanipulasi data dalam tabel. Apakah
SELECT .. eksekusi "aman"? Bisakah kueri memengaruhi data dalam tabel?
Jawaban untuk 2.4Pertanyaannya mungkin tampak primitif, namun ...
Pada awal belajar SQL, saya berpendapat bahwa pernyataan ini hanya dapat menampilkan data, tetapi:
Selain fakta bahwa SELECT dapat mengunci tabel untuk perubahan (MULAI; PILIH ... UNTUK PEMBARUAN) *
SELECT dapat memanggil fungsi yang dapat melakukan hampir semua manipulasi.
Pemula perlu segera memahami hal ini, dan tidak setelah menyelesaikan permintaan "informasi kecil" di server Produksi
3. Hanya PostgreSQL
3.1 Jelaskan apa yang terjadi ketika kueri ini dieksekusi dalam dialog SQL:
SELECT * INTO wtf FROM pg_stat_activity;
Balas ke 3.1Biasanya, SELECT INTO digunakan dalam fungsi
plpgsql untuk menulis nilai ke variabel.
Di luar plpgsql, efek dari perintah akan mirip dengan permintaan di bawah ini:
CREATE TABLE wtf AS SELECT * FROM pg_stat_activity;
3.2 apa yang akan ditampilkan permintaan "sederhana" ini
SELECT wtf_ FROM pg_stat_activity AS wtf_ ;
Balas ke 3.2pg_stat_activity system view (VIEW) dari proses aktif dalam database.
Keunikan kueri adalah bahwa satu kolom dengan baris (ROW) yang memiliki TYPE pg_stat_activity (atau tabel lain) akan ditampilkan. Anda harus mengetahui hal ini lebih cepat bagi mereka yang menulis fungsi. Anda dapat membaca lebih lanjut di
manual.Pertanyaan itu ditambahkan karena seorang pemula dapat dengan mudah mendapatkan hasil seperti itu secara tidak sengaja, dan tidak mengerti apa masalahnya
4. Bekerja dengan teks. Ekspresi reguler
Saya pikir Anda harus dapat tidak hanya membangun kueri, tetapi juga menyajikan hasilnya dengan cara yang benar.
Ekspresi reguler adalah topik besar yang terpisah, dengan banyak artikel berkualitas. Karena itu, saya hanya akan menunjukkan contoh, tanpa penjelasan rinci.
4.1. Misalkan ada tabel "
table_5 " dengan kolom teks "
X " dan banyak baris berbeda. Permintaan apa yang bisa mendapatkan 10 karakter terakhir dari setiap baris?
Balas ke 4.1SQL memungkinkan Anda menemukan banyak solusi untuk masalah yang sama, misalnya:
hal paling sederhana yang terlintas dalam pikiran adalah benar (X, 10)
regex dapat digunakan: substring (X, '. {0,10} $')
Anda bahkan dapat nakostylyat "menghindar" (dalam semua pengertian) seperti ini: mundur (substring (mundur (X) selama 10))
4.2 Ada tabel βtable_6β dengan kolom teks βXβ. Tabel berisi satu baris (semua teks dalam bahasa Inggris dan Rusia saja):
'Lorem 3 Ipsum 23 standard 7 dummy 17 text Ultimate Answer of Life ?? 777'
A) Tulis kueri yang akan mengembalikan karakter ke-42 ke 68 dari string ini
B) Bagaimana cara mengekstrak hanya huruf kapital (Rusia atau Inggris) dalam sebuah string menggunakan SQL?
C) Cara menghitung jumlah angka (
bukan angka ) dalam suatu string menggunakan SQL
Sketsa SQL WITH table_6(X) AS( SELECT 'Lorem 3 Ipsum 23 standard 7 dummy 17 text Ultimate Answer of Life ?? 777'::TEXT ) SELECT X FROM table_6
4.3 Bagaimana cara mengganti semua spasi ganda (tiga kali lipat atau lebih) dengan satu spasi dalam teks (sel tabel)? (berdasarkan tradisi: tabel "
table_7 " dengan kolom "
X ") (PS itu akan cukup untuk menulis
SELECT mengembalikan hasil yang diinginkan, dan bukan
UPDATE table_7 ... )
Balas ke 4.3 WITH table_7(X) AS (SELECT 'Lorem 3 Ipsum 23 standard 7 dummy 11 text'::TEXT)
4.4 Ada string "
X " di mana kesalahan ketik diizinkan. Alih-alih huruf Rusia (e, o, s, C), karakter luar yang mirip dari alfabet Inggris digunakan. Ganti karakter ini dengan SQL.
PS Baris harus hanya berisi karakter Rusia, dan Anda tidak perlu khawatir tentang kemungkinan perubahan kata-kata bahasa Inggris.
(Jika Anda mengalami kesulitan mengganti semua karakter, ganti setidaknya satu)
Baris contoh:
X = 'Coeo eoc oe'
4.5 Tulis kueri yang mengonversi string:
' Ivan Ivanov dan Ivanovich' untuk spesies
'Ivan IvanovPencarian bonus untuk mereka yang mengatasinyaHebat jika ada fungsi yang sudah jadi
Bisakah Anda mengonversi sebaliknya? (lebih disukai tanpa kehilangan bantalan).
Mungkin tugasnya tidak khas, tetapi akan berguna untuk pengembangan.
'IVANOV IVAN IVANOVICH' dikonversi menjadi 'IVANOV IVAN IVANOVICH'
dan membalikkan kasus?
Respon Tantangan Bonus SELECT string_agg(LOWER(LEFT(x,1)) || UPPER(SUBSTRING(x from 2)), '' ORDER BY rn) FROM (SELECT * FROM regexp_split_to_table(' 4 TesT', '\y') WITH ORDINALITY y(x, rn) ) AS z
5. Sedikit tentang transaksi
Transaksi adalah hal yang sangat penting dalam DBMS, penting untuk memahami poin utama.
Saya akan mencoba mensimulasikan contoh:
Misalkan ada tabel "barang" dengan dua pengguna yang akan bekerja.
Ini memiliki kolom
diskon integer sama dengan
10 untuk semua baris.
Pengaturan basis data adalah standar (READ COMMITTED - read data berkomitmen).
Pengguna
User_1 membuka transaksi, menjalankan permintaan berikut:
BEGIN; UPDATE goods SET discount = discount + 5;
Sedetik kemudian, pengguna lain (
User_2 )
Ia melakukan permintaan yang hampir sama tanpa membuka transaksi:
UPDATE goods SET discount = discount + 10;
Menurut Anda apa yang akan terjadi dalam situasi berikut:
A) Apa hasil yang akan diperoleh User_2 jika User_1 membiarkan transaksi terbuka (mis. Tidak mengkonfirmasi transaksi / tidak mengembalikan perubahan)?
Apa yang User_1 akan lihat berdasarkan permintaan:
SELECT discount FROM goods LIMIT 1;
B) Apa yang terjadi jika User_1 melakukan ROLLBACK? Apa hasil yang akan diperoleh User_2?
T) Apa yang terjadi jika User_1 melakukan COMMIT? Apa hasil yang akan diperoleh User_2?
JawabannyaSejauh yang saya tahu, READ UN COMMITTED tidak didukung di PostgreSQL, dan data kotor (tidak dikonfirmasi) tidak dapat dibaca
Jawabannya adalah sebagai berikut:
A) Permintaan User_2 akan menunggu COMMIT atau ROLLBACK dari User_1. (permintaan tampaknya membeku)
User_1 dalam transaksinya akan melihat snapshot database versi miliknya, di mana diskon sudah sama dengan 15
B) Jika User_1 melakukan ROLLBACK, maka nilai diskon akan tetap sama, dan kemudian User_2 akan dieksekusi, yang akan menambahkan 10 ke diskon dan diskon akan menjadi 20
C) Jika User_1 melakukan KOMIT, maka nilai diskon akan meningkat sebesar 5, dan kemudian User_2 akan dieksekusi, yang akan menambahkan 10 ke diskon dan diskon akan menjadi 25
Versi lain dari tugas iniVersi tugas 13 yang sedikit berbeda dari pengguna
kirill_petrov pada READ COMMITTED
Data apa yang akan ada dalam tabel?
Kesimpulan
Saya pikir itu menyentuh poin yang cukup menarik.
Saya berharap tugas-tugas ini akan membantu memotivasi pemula, karena membosankan mempelajari sesuatu tanpa tujuan / sasaran / arah tertentu.
Saya bisa senang untuk mereka yang mudah menjawab semua pertanyaan. Dan mereka yang memiliki kesulitan, saya harap, mendapat
tendangan ke arah pembangunan. Mereka yang tidak mengerti banyak, tetapi ingin belajar SQL, saya mengundang
kursus pejuang muda PostgreSQL ke artikel terakhir saya.
Saya menantikan penambahan, solusi untuk masalah yang sangat menarik (Anda dapat menambang) dan komentar lainnya!
Terima kasih atas perhatian anda! Semoga sukses dalam belajar SQL!