Apakah ada cara untuk SELECT
semua kolom dalam sebuah tabel, kecuali yang spesifik? Akan sangat mudah untuk memilih semua kolom non-gumpalan atau non-geometris dari sebuah tabel.
Sesuatu seperti:
SELECT * -the_geom FROM segments;
- Saya pernah mendengar bahwa fungsi ini sengaja dikecualikan dari standar SQL karena mengubah menambahkan kolom ke tabel akan mengubah hasil kueri. Apakah ini benar? Apakah argumennya valid?
- Apakah ada solusinya, terutama di PostgreSQL?
postgresql
sql-standard
Adam Matan
sumber
sumber
name
,age
,sid
) yang cocok baik ke layar lebar, disertai biner panjanggeom
kolom. Saya ingin menanyakan semua bidang kecuali biner geometri, dan menulis nama mereka satu per satu itu membosankan.select (!coluns2,!column5) from sometable;
Jawaban:
Fitur seperti itu tidak ada di Postgres maupun SQL Standard (AFAIK). Saya pikir ini adalah pertanyaan yang cukup menarik jadi saya mencari sedikit di Google dan menemukan artikel yang menarik di postgresonline.com .
Mereka menunjukkan pendekatan yang memilih kolom langsung dari skema:
Anda dapat membuat fungsi yang melakukan sesuatu seperti itu. Topik-topik semacam itu juga dibahas di milis, tetapi keseluruhan konsensus hampir sama: menanyakan skema.
Saya yakin ada solusi lain, tapi saya pikir mereka semua akan melibatkan semacam skema sihir-queriying-foo.
BTW: Berhati-hatilah
SELECT * ...
karena ini dapat memiliki penalti kinerjasumber
Jawaban sebenarnya adalah Anda tidak bisa melakukannya secara praktis. Ini telah menjadi fitur yang diminta selama beberapa dekade dan pengembang menolak untuk mengimplementasikannya.
Jawaban populer yang menyarankan kueri tabel skema tidak akan dapat berjalan secara efisien karena pengoptimal Postgres menganggap fungsi dinamis sebagai kotak hitam (lihat kotak uji di bawah). Itu berarti bahwa indeks tidak akan digunakan dan bergabung tidak akan dilakukan secara cerdas. Anda akan jauh lebih baik dengan semacam sistem makro seperti m4. Setidaknya itu tidak akan membingungkan pengoptimal (tetapi mungkin masih membingungkan Anda.) Tanpa memalsukan kode dan menulis fitur sendiri atau menggunakan antarmuka bahasa pemrograman Anda terjebak.
Saya menulis bukti sederhana konsep di bawah ini yang menunjukkan betapa buruknya kinerja dengan eksekusi dinamis yang sangat sederhana di plpgsql. Perhatikan juga, bahwa di bawah ini saya harus memaksa fungsi mengembalikan catatan generik ke jenis baris tertentu dan menghitung kolom. Jadi metode ini tidak akan berfungsi untuk 'pilih semua kecuali' kecuali Anda ingin membuat kembali fungsi ini untuk semua tabel Anda.
Seperti yang Anda lihat, pemanggilan fungsi memindai seluruh tabel sementara kueri langsung menggunakan indeks ( 95,46 ms vs 00,07 ms .) Jenis-jenis fungsi ini akan menyaring segala jenis kueri rumit yang diperlukan untuk menggunakan indeks atau bergabung dengan tabel dalam urutan yang benar. .
sumber
Sebenarnya agak mungkin dengan PostgreSQL dimulai dengan 9,4 di mana JSONB diperkenalkan. Saya sedang memikirkan pertanyaan serupa tentang cara menampilkan semua atribut yang tersedia di Google Map (via GeoJSON).
johto pada saluran irc disarankan untuk mencoba menghapus elemen dari JSONB.
Inilah idenya
Sementara Anda mendapatkan json, bukan kolom individual, itu persis apa yang saya inginkan. Mungkin json dapat diperluas kembali ke kolom individual.
sumber
Satu-satunya cara Anda dapat (jangan katakan Anda harus) melakukannya adalah dengan menggunakan pernyataan sql dinamis. Sangat mudah (seperti yang ditulis DrColossos) untuk menanyakan tampilan sistem dan menemukan struktur tabel dan membuat pernyataan yang benar.
PS: Mengapa Anda ingin memilih semua / beberapa kolom tanpa mengetahui / menulis persis struktur tabel Anda?
sumber
Secara dinamis seperti yang dinyatakan di atas adalah satu-satunya jawaban tetapi saya tidak akan merekomendasikannya. Bagaimana jika Anda menambahkan lebih banyak kolom dalam jangka panjang tetapi belum tentu diperlukan untuk permintaan itu?
Anda akan mulai menarik lebih banyak kolom daripada yang Anda butuhkan.
Bagaimana jika pilih adalah bagian dari sisipan seperti pada
Masukkan ke tableA (col1, col2, col3 .. coln) Pilih semuanya kecuali 2 kolom dari tabelB
Kecocokan kolom akan salah dan sisipan Anda akan gagal.
Itu mungkin tetapi saya masih menyarankan untuk menulis setiap kolom yang diperlukan untuk setiap pilih yang ditulis walaupun hampir setiap kolom diperlukan.
sumber
SELECT
s.Jika tujuan Anda adalah untuk menghapus kekacauan dari layar selama proses debug dengan tidak menampilkan kolom dengan nilai data yang besar, maka Anda dapat menggunakan trik berikut:
(instal paket contrib "hstore" jika Anda belum memilikinya: "
CREATE EXTENSION hstore;
")Untuk tabel "test" dengan col1, col2, col3, Anda dapat mengatur nilai "col2" menjadi nol sebelum menampilkan:
Atau, atur dua kolom ke nol sebelum menampilkan:
peringatannya adalah bahwa "test" harus berupa tabel (alias atau subselect tidak akan berfungsi) karena tipe record yang dimasukkan ke hstore harus didefinisikan.
sumber
Ada solusi yang baru saja saya temukan, tetapi diperlukan untuk mengirim pertanyaan SQL dari dalam R. Mungkin bermanfaat bagi pengguna R.
Pada dasarnya
dplyr
paket mengirimkan SQL (dan khususnya PostgreSQL) permintaan dan menerima-(column_name)
argumen.Jadi contoh Anda dapat ditulis sebagai berikut:
sumber
Dalam komentar Anda menjelaskan bahwa motif Anda adalah untuk memiliki kenyamanan tidak menampilkan konten kolom dengan konten yang panjang, daripada tidak menampilkan kolom itu sendiri:
Ini dimungkinkan, dengan bantuan fungsi pembantu yang menggantikan konten lama dengan
null
(text
kolom apa pun dalam contoh saya, tetapi Anda akan memodifikasi itu untuk jenis yang ingin Anda tekan):Aku di sini
sumber
Dari perspektif aplikasi, ini adalah solusi malas. Aplikasi tidak mungkin secara otomatis tahu apa yang harus dilakukan dengan kolom baru.
Aplikasi peramban data dapat meminta metadata untuk data dan mengecualikan kolom dari kueri yang sedang dijalankan, atau memilih subset dari data kolom. Gumpalan baru dapat dikecualikan saat ditambahkan. Data BLOB untuk baris tertentu dapat dipilih sesuai permintaan.
Dalam varian SQL apa pun yang mendukung kueri dinamis, kueri dapat dibuat menggunakan kueri pada tabel meta data. Untuk maksud Anda, saya akan mengecualikan kolom berdasarkan jenis daripada nama.
sumber
Anda tidak pernah melihat
*
di SQL-VIEWS ... periksa\d any_view
dipsql
. Ada preprocessing (introspektif) untuk representasi internal.Semua diskusi di sini menunjukkan bahwa yang masalah usulan (tersirat dalam pertanyaan dan diskusi) adalah gula sintaks untuk programmer, bukan "masalah optimasi SQL" nyata ... Nah, saya duga, itu adalah untuk 80% dari programmer.
Jadi dapat diimplementasikan sebagai " pre-parsing dengan introspeksi" ... Lihat apa yang PostgreSQL lakukan ketika Anda mendeklarasikan SQL-VIEW dengan
SELECT *
: konstruktor-VIEW berubah*
menjadi daftar semua kolom (dengan introspeksi dan pada saat Anda menjalankan BUAT LIHAT sumber-kode).Implementasi untuk CREATE VIEW dan SIAPKAN
Ini adalah implementasi yang layak. Misalkan meja
t
dengan bidang(id serial, name text, the_geom geom)
.Sama untuk pernyataan SIAPKAN .
... jadi, itu mungkin, dan itulah yang dibutuhkan 80% programmer, gula sintaksis untuk SIAPKAN dan LIHAT!
CATATAN: tentu saja sintaks yang layak mungkin tidak
- column_name
, jika ada beberapa konflik di PostgreSQL, jadi kami dapat menyarankanEXCEPT column_name
,EXCEPT (column_name1, column_name2, ..., column_nameN)
atau yang lainnya.sumber
Ini adalah fungsi saya untuk memilih semua kolom yang diharapkan. Saya menggabungkan ide dari postgresonline.com dan postgresql tuturial dan dari sumber lain.
sumber