Saya merasa sangat sulit untuk menulis query SQL kompleks yang melibatkan gabungan banyak (setidaknya 3-4) tabel dan melibatkan beberapa kondisi bersarang. Pertanyaan yang saya minta untuk dituliskan dengan mudah dijelaskan oleh beberapa kalimat, tetapi dapat membutuhkan sejumlah kode untuk menyelesaikannya. Saya menemukan diri saya sering menggunakan tampilan sementara untuk menulis pertanyaan ini, yang tampak seperti sedikit penopang. Kiat apa yang dapat Anda berikan yang dapat saya gunakan untuk membuat kueri kompleks ini lebih mudah? Lebih khusus lagi, bagaimana cara memecah pertanyaan ini menjadi langkah-langkah yang perlu saya gunakan untuk benar-benar menulis kode SQL?
Perhatikan bahwa saya SQL yang diminta untuk saya tulis adalah bagian dari pekerjaan rumah untuk kursus basis data, jadi saya tidak ingin perangkat lunak yang akan melakukan pekerjaan untuk saya. Saya ingin benar-benar memahami kode yang saya tulis.
Lebih detail teknis:
- Basis data di-host pada server PostgreSQL yang berjalan di mesin lokal.
- Basis datanya sangat kecil: tidak ada lebih dari tujuh tabel dan tabel terbesar memiliki kurang dari 50 baris.
- Kueri SQL diteruskan tidak berubah ke server, melalui Pangkalan LibreOffice.
Jawaban:
Saya mendasarkan sebagian besar ini pada hanya mencoba untuk mendapatkan jawaban yang "benar", sehingga Anda mungkin menemukan ada beberapa masalah kinerja. Tidak ada gunanya mempercepat permintaan yang salah.
Memahami hubungan tabel - Kebanyakan akan menjadi satu ke banyak. Ketahui tabel "banyak". Identifikasi bidang yang diperlukan untuk bergabung Anda.
Pikirkan tentang skenario bergabung LEFT - Pilih semua karyawan dan gaji mereka dari bulan lalu. Bagaimana jika mereka tidak menerima gaji bulan lalu?
Ketahui set hasil: 1) Dalam spreadsheet, masukkan secara manual setidaknya satu catatan yang benar untuk kueri Anda. 2) Tulis kueri dalam bentuk yang cukup sederhana untuk mengidentifikasi berapa banyak catatan yang harus dikembalikan. Gunakan keduanya untuk menguji kueri Anda untuk memastikan bergabung dengan tabel baru tidak mengubah hasil.
Pisahkan permintaan Anda menjadi beberapa bagian yang dapat dikelola - Anda tidak harus menulis semuanya sekaligus. Query yang kompleks terkadang hanya bisa menjadi kumpulan queries sederhana.
Waspadai tingkat agregasi campuran : Jika Anda harus memasukkan nilai bulanan, triwulanan, dan tahun-ke-tanggal dalam hasil yang sama, Anda harus menghitungnya secara terpisah dalam kueri yang dikelompokkan pada nilai yang berbeda.
Ketahui kapan harus UNION Terkadang lebih mudah untuk memecah subkelompok menjadi pernyataan pilihan mereka sendiri. Jika Anda memiliki tabel yang dicampur dengan manajer dan karyawan lain, dan pada setiap kolom Anda harus melakukan pernyataan Kasus berdasarkan keanggotaan di salah satu dari kelompok ini, mungkin lebih mudah untuk menulis kueri Manajer dan menyatukan ke kueri Karyawan. Masing-masing akan mengandung logikanya sendiri. Harus menyertakan item dari tabel yang berbeda di baris yang berbeda adalah penggunaan yang jelas.
Rumus Kompleks / Bertumpuk - Cobalah membuat indentasi secara konsisten dan jangan takut untuk menggunakan banyak baris. "KASUS KAPAN KASUS KASUS KAPAN" akan membuat Anda gila. Luangkan waktu untuk memikirkan semua ini. Simpan kalori kompleks untuk yang terakhir. Dapatkan catatan yang benar dipilih terlebih dahulu. Lalu, Anda menyerang rumus rumit yang mengetahui Anda bekerja dengan nilai yang benar. Melihat nilai yang digunakan dalam rumus akan membantu Anda melihat area di mana Anda harus memperhitungkan nilai NULL dan di mana menangani pembagian dengan kesalahan nol.
Tes sesering mungkin saat Anda menambahkan tabel baru untuk memastikan Anda masih mendapatkan hasil yang diinginkan dan mengetahui yang bergabung atau klausa adalah penyebabnya.
sumber
Lekukan akan menjadi hal pertama yang harus dilakukan, jika Anda belum melakukannya. Tidak hanya itu berguna bahkan dengan kueri sederhana, tetapi sangat penting ketika datang untuk bergabung dan meminta sedikit lebih kompleks daripada a
select top 1 [ColumnName] from [TableName]
.Setelah menjorok dengan benar, tidak ada yang melarang untuk menambahkan komentar di dalam kueri itu sendiri, jika perlu. Jangan terlalu sering menggunakannya: jika kodenya cukup eksplisit, menambahkan komentar hanya akan merusak kejelasan kode. Tetapi mereka tetap diterima untuk bagian-bagian yang kurang eksplisit dari permintaan.
Perhatikan bahwa kueri yang lebih panjang (termasuk kueri dengan komentar) akan berarti penggunaan bandwidth yang lebih besar antara server aplikasi Anda dan server database Anda. Perhatikan juga bahwa kecuali Anda bekerja pada produk skala Google dengan jumlah permintaan yang sangat besar per detik, membutuhkan kinerja yang luar biasa dan penggunaan sumber daya, ukuran yang ditambahkan oleh komentar tidak dapat mengubah apa pun untuk Anda dalam hal kinerja.
Menegakkan gaya yang sama di atas tabel, kolom, dll. Juga membantu keterbacaan banyak. Ketika database warisan memiliki meja
PRODUCT
,users
,USERS_ObsoleteDONT_USE
,PR_SHIPMENTS
danHRhbYd_UU
, seseorang melakukan sesuatu yang sangat salah.Menegakkan gaya yang sama atas permintaan juga penting. Misalnya jika Anda menulis query untuk Microsoft SQL Server dan Anda memutuskan untuk menggunakan
[TableName]
bukanTableName
, tongkat dengan itu. Jika Anda pergi ke baris baru setelah aselect
, jangan lakukan hanya dalam setengah dari pertanyaan Anda, tetapi semuanya.Jangan gunakan
*
, kecuali ada alasan kuat untuk melakukannya (seperti diif exists(select * from [TableName] where ...)
dalam Microsoft SQL Server). Tidak hanya*
memiliki dampak kinerja negatif di beberapa (jika tidak sebagian besar) database, tetapi juga tidak membantu bagi pengembang yang menggunakan kueri Anda. Dengan cara yang sama, pengembang harus mengakses nilai berdasarkan nama, tidak pernah dengan indeks.Akhirnya, untuk pilihan, tidak ada yang salah dalam memberikan tampilan . Untuk hal lain, prosedur tersimpan dapat juga digunakan tergantung pada proyek dan orang-orang yang bekerja dengan Anda.
¹ Beberapa orang membenci prosedur tersimpan. Orang lain tidak suka mereka karena beberapa alasan (valid sempurna, setidaknya untuk mereka).
² Kolega Anda, siswa lain, guru Anda, dll.
sumber
Sedikit tembakan dalam kegelapan di sini, tetapi jika Anda menulis banyak pandangan sementara mungkin Anda belum menyadari bahwa sebagian besar tempat Anda bisa meletakkan tabel dalam pernyataan SQL, tabel itu dapat diganti dengan kueri.
Jadi, daripada bergabung dengan tabel A ke tampilan sementara B, Anda dapat bergabung dengan tabel A ke kueri yang telah Anda gunakan sebagai tampilan sementara B. Misalnya:
Contoh ini agak tidak berguna, tetapi harus menjelaskan sintaksisnya.
Untuk tampilan yang bukan "spesial" (diindeks, dipartisi) ini akan menghasilkan rencana permintaan yang sama seperti jika Anda menggunakan tampilan.
Sejauh membuatnya lebih mudah untuk menulis, Anda dapat memverifikasi setiap bagian untuk memastikan Anda mendapatkan apa yang Anda harapkan sebelum menuliskan seluruh permintaan.
Saya minta maaf jika ini topi lama untuk Anda.
sumber
Alih-alih pandangan sementara, menggunakan klausa WITH . Ini membuatnya lebih mudah untuk memecah pertanyaan besar menjadi bagian-bagian kecil yang lebih mudah dibaca.
sumber
sumber
Seperti yang lainnya, Anda ingin memecah masalah menjadi beberapa bagian yang dapat dikelola.
Ngomong-ngomong, itu memang cara Anda memecahkan masalah yang rumit.
Jadi: Anda ingin memeriksa subquery untuk melihat apakah itu benar-benar mengembalikan apa yang Anda inginkan sebelum menjalankan kueri luar di atasnya. Anda ingin mencoba gabungan minimal dari setiap tabel yang Anda ikuti sehingga Anda dapat melihat bahwa Anda benar-benar memikirkannya dengan baik. Hal-hal seperti itu. Berharap untuk mengetik semuanya dan keluar persis seperti yang Anda inginkan dalam satu pukulan saja tidak realistis.
Pernyataan SQL, setelah mencapai tingkat kerumitan tertentu, pada dasarnya adalah sebuah program kecil. Itu membuat perbedaan besar untuk benar-benar memahami bagaimana data digabungkan, dipilih, difilter, dan keluaran.
sumber