Saya punya tabel seperti ini:
ID | Val | Kind
----------------------
1 | 1337 | 2
2 | 1337 | 1
3 | 3 | 4
4 | 3 | 4
Saya ingin membuat SELECT
yang akan mengembalikan hanya baris pertama untuk masing-masing Val
, memesan oleh Kind
.
Output sampel:
ID | Val | Kind
----------------------
2 | 1337 | 1
3 | 3 | 4
Bagaimana saya bisa membangun kueri ini?
oracle
greatest-n-per-group
BrunoLM
sumber
sumber
ORDER BY ID DESC
, tapi itu tidak relevan untuk pertanyaan. Dalam contoh ini saya tidak peduli.Jawaban:
Solusi ini juga menggunakan
keep
, tetapival
dankind
juga dapat dengan mudah dihitung untuk setiap grup tanpa subquery:Aku di sini
TETAP… PERTAMA dan TETAP… LAST adalah fitur agregat khusus Oracle - Anda dapat membaca tentang itu di sini di dokumen Oracle, atau di ORACLE_BASE :
sumber
Gunakan ekspresi tabel umum (CTE) dan fungsi windowing / peringkat / partisi seperti ROW_NUMBER .
Kueri ini akan membuat tabel dalam-memori yang disebut ORDERED dan menambahkan kolom tambahan rn yang merupakan urutan angka dari 1 hingga N. PARTITION BY mengindikasikan bahwa ia harus dimulai ulang pada 1 setiap kali nilai perubahan Val dan kami ingin memesan baris dengan nilai terkecil dari Jenis.
Pendekatan di atas harus bekerja dengan RDBMS yang telah menerapkan fungsi ROW_NUMBER (). Oracle memiliki beberapa fungsi yang elegan sebagaimana dinyatakan dalam jawaban mik yang umumnya akan menghasilkan kinerja yang lebih baik daripada jawaban ini.
sumber
solusi bilinkc bekerja dengan baik, tapi saya pikir saya akan membuang milik saya juga. Ini memiliki biaya yang sama, tetapi mungkin lebih cepat (atau lebih lambat, saya belum mengujinya). Perbedaannya adalah ia menggunakan First_Value alih-alih Row_Number. Karena kita hanya tertarik pada nilai pertama, dalam pikiranku itu lebih mudah.
Data Uji.
Jika Anda suka, di sini adalah setara CTE.
sumber
id
unik.Anda dapat menggunakan
keep
untuk memilihid
dari setiap grup:Aku di sini
sumber
sumber