Lebih
Bagaimana saya (atau saya) PILIH BERBEDA pada beberapa kolom?
Saya perlu untuk mengambil semua baris dari tabel yang mana 2 kolom gabungan semua berbeda. Jadi saya ingin semua penjualan yang tidak memiliki penjualan yang terjadi pada hari yang sama untuk harga yang sama. Penjualan yang unik berdasarkan hari dan harga yang akan mendapatkan update ke status aktif.
Jadi saya'm berpikir:
UPDATE sales
SET status = 'ACTIVE'
WHERE id IN (SELECT DISTINCT (saleprice, saledate), id, count(id)
FROM sales
HAVING count = 1)
Tapi otak saya sakit akan lebih jauh dari itu.
382
5
adalah roughly setara dengan:
It's merupakan ide yang baik untuk mendapatkan digunakan untuk KELOMPOK DENGAN sintaks, seperti's lebih kuat.
Untuk pertanyaan anda, saya'd lakukan seperti ini:
Jika anda menempatkan bersama-sama jawaban sejauh ini, membersihkan dan memperbaiki, anda akan tiba di segala query:
Yang banyak lebih cepat daripada salah satu dari mereka. Nuklir kinerja saat ini jawaban yang diterima oleh faktor 10 - 15 (dalam tes saya pada PostgreSQL 8.4 dan 9.1).
Tapi ini masih jauh dari optimal. Gunakan
TIDAK ADA
(anti-)semi-bergabung untuk kinerja yang lebih baik.ADA
adalah standar SQL, telah sekitar selamanya (setidaknya sejak PostgreSQL 7.2, jauh sebelum pertanyaan ini diminta) dan cocok disajikan persyaratan sempurna:db<>biola di sini Old SQL Biola
Kunci unik mengidentifikasi baris
Jika anda don't memiliki primary atau unique key untuk tabel (
id
dalam contoh), anda dapat mengganti dengan sistem kolomctid
untuk tujuan ini query (tetapi tidak untuk beberapa tujuan lain):Setiap tabel harus memiliki primary key. Tambahkan satu jika anda tidak't memiliki satu, belum. Saya sarankan
serial
atauIDENTITAS
kolom di Postgres 10+.Terkait:
Cara ini lebih cepat?
Subquery dalam
ADA
anti-semi-bergabung dapat berhenti mengevaluasi sesegera pertama dupe ditemukan (tidak ada gunanya melihat lebih jauh). Untuk sebuah meja dengan beberapa duplikat ini hanya sedikit lebih efisien. Dengan banyak duplikat ini menjadi cara lebih efisien.Mengecualikan kosong update
Untuk baris yang sudah memiliki
status = 'AKTIF'
update ini tidak akan mengubah apa pun, tapi masih menyisipkan baris baru versi penuh biaya (minor pengecualian berlaku). Biasanya, anda tidak ingin ini. Tambahkan lagidi MANA
kondisi seperti yang ditunjukkan di atas untuk menghindari hal ini dan membuatnya bahkan lebih cepat:Jika
status
didefinisikanNOT NULL
, anda dapat menyederhanakan untuk:Perbedaan yang halus dalam NULL penanganan
Query ini (tidak seperti saat ini jawaban yang diterima oleh Joel) tidak memperlakukan nilai-nilai NULL sama. Dua baris berikut untuk
(saleprice, saledate)
akan memenuhi syarat sebagai "yang berbeda" (meskipun tampak identik dengan mata manusia):Juga lewat di indeks unik dan hampir di mana pun, karena nilai-nilai NULL tidak membandingkan sama sesuai dengan standar SQL. Lihat:
OTOH,
GROUP BY
,BERBEDA
atauBERBEDA PADA ()
mengobati NULL nilai-nilai yang sama. Menggunakan query yang sesuai gaya tergantung pada apa yang ingin anda capai. Anda masih dapat menggunakan ini lebih cepat query denganINI TIDAK BERBEDA DARI
bukan=
untuk setiap atau semua perbandingan untuk membuat NULL membandingkan sama. Lebih lanjut:Jika semua kolom yang dibandingkan didefinisikan
NOT NULL
, tidak ada ruang untuk perbedaan pendapat.Masalah dengan query anda adalah bahwa ketika menggunakan GROUP BY clause (yang pada dasarnya dilakukan dengan menggunakan distinct) anda hanya dapat menggunakan kolom yang anda grup atau fungsi agregat. Anda tidak dapat menggunakan kolom id karena ada potensi nilai-nilai yang berbeda. Dalam kasus anda hanya selalu ada satu nilai karena MEMILIKI klausa, tetapi sebagian besar RDBMS tidak cukup pintar untuk menyadari bahwa.
Ini harus bekerja namun (dan doesn't perlu bergabung):
Anda juga bisa menggunakan MAX atau AVG bukan MIN, itu hanya penting untuk menggunakan sebuah fungsi yang mengembalikan nilai dari kolom jika hanya ada satu baris pencocokan.
Saya ingin memilih nilai-nilai yang berbeda dari satu kolom 'GrondOfLucht' tapi mereka harus diurutkan dalam urutan seperti yang diberikan dalam kolom 'sortering'. Saya tidak bisa mendapatkan nilai yang berbeda hanya menggunakan satu kolom
Hal ini juga akan memberikan kolom 'sortering' dan karena 'GrondOfLucht' DAN 'sortering' adalah tidak unik, hasilnya akan SEMUA baris.
gunakan GRUP untuk memilih catatan 'GrondOfLucht' dalam urutan yang diberikan oleh 'sortering
Jika anda DBMS doesn't dukungan berbeda dengan beberapa kolom seperti ini:
Multi-pilih secara umum dapat dilaksanakan dengan aman sebagai berikut:
Karena hal ini dapat bekerja pada sebagian besar DBMS dan ini diharapkan akan lebih cepat daripada kelompok dengan solusi seperti yang anda menghindari pengelompokan fungsi.