Mengekalkan Baris Terbaharu bagi Setiap Kunci
Corak “rekod paling terkini bagi setiap pelanggan” dengan partition mengikut kunci dan susunan mengikut tarikh
Mengekalkan Baris Terbaharu bagi Setiap Kunci ialah pelajaran Persediaan Temu Duga Pengaturcaraan percuma di CoddyKit. Ini ialah pelajaran 4 daripada 4. Anda boleh membaca keseluruhan pelajaran di bawah secara percuma — kemudian berlatih secara praktikal dalam pelayar menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Persediaan Temu Duga Pengaturcaraan, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Persediaan Temu Duga Pengaturcaraan merangkumi sejumlah 4 pelajaran.
Soalan Rekod Paling Terkini bagi Setiap Kunci
"Kembalikan pesanan paling terkini bagi setiap pelanggan." "Dapatkan status terkini bagi setiap peranti." Masalah rekod terkini bagi setiap kunci ini ialah antara tugasan temu duga SQL yang paling kerap ditanya kerana ia sentiasa muncul dalam kerja analitis sebenar.
Ini ialah kes khusus rekod pertama bagi setiap kumpulan: bahagikan mengikut kunci, susun mengikut cap masa secara menurun, dan kekalkan baris pertama. Pelajaran ini mengukuhkan corak tersebut serta alternatifnya.
Mengapa MAX Sahaja Tidak Mencukupi
Jawapan pertama yang menggoda ialah MAX(order_date) yang dikumpulkan mengikut pelanggan. Itu memberikan tarikh terkini, tetapi bukan baris selebihnya bagi pesanan tersebut, id pesanan, amaun atau status.
Jika penemuduga mahukan keseluruhan baris terkini, MAX dengan GROUP BY memerlukan cantuman tambahan kembali ke jadual berdasarkan kunci dan tarikh maksimum, yang panjang lebar dan boleh gagal apabila berlaku seri. Fungsi tetingkap lebih kemas.
-- Gives the date, not the full row
SELECT customer_id, MAX(order_date) AS last_order
FROM orders
GROUP BY customer_id;Corak ROW_NUMBER
Bahagikan mengikut kunci, susun mengikut cap masa secara menurun, dan baris terkini akan mendapat rn = 1. Kekalkan hanya baris tersebut dan anda memperoleh rekod penuh yang paling terkini bagi setiap kunci.
Inilah jawapan utama. Ia mengembalikan tepat satu baris bagi setiap kunci walaupun cap masa seri, yang biasanya dimaksudkan oleh frasa "baris terkini".
WITH ranked AS (
SELECT *,
ROW_NUMBER() OVER (
PARTITION BY customer_id
ORDER BY order_date DESC
) AS rn
FROM orders
)
SELECT customer_id, order_id, order_date, amount
FROM ranked
WHERE rn = 1;Memecahkan Seri Cap Masa
Dua pesanan bagi pelanggan yang sama boleh berkongsi order_date, sama ada pada hari yang sama atau dengan cap masa yang serupa. Tanpa pemecah seri, baris yang menjadi rn = 1 dipilih secara sewenang-wenangnya dan mungkin berubah antara satu pelaksanaan dengan pelaksanaan yang lain.
Tambahkan kunci sekunder yang unik seperti order_id DESC supaya baris terkini ditentukan secara konsisten. Penemuduga biasanya menguji sama ada anda menyedari kes pinggiran ini.
ROW_NUMBER() OVER (
PARTITION BY customer_id
ORDER BY order_date DESC, order_id DESC
) AS rnRekod Terkini atau Semua yang Seri
Tentukan maksud "terkini" apabila cap masa seri:
- Jika mahukan tepat satu baris bagi setiap kunci → gunakan
ROW_NUMBERdengan pemecah seri. - Jika mahukan semua baris yang berkongsi cap masa maksimum → gunakan
RANK() = 1, yang mengembalikan setiap baris terkini yang seri.
Mengajukan soalan penjelasan ini menunjukkan bahawa anda memahami semantik, bukan sekadar sintaks.
WITH ranked AS (
SELECT *,
RANK() OVER (
PARTITION BY customer_id ORDER BY order_date DESC
) AS rnk
FROM orders
)
SELECT * FROM ranked WHERE rnk = 1;Alternatif Subpertanyaan Berkorelasi
Sebelum fungsi tetingkap digunakan secara meluas, jawapan bagi rekod terkini setiap kunci menggunakan subpertanyaan berkorelasi: kekalkan sesuatu baris hanya jika tiada baris lain bagi kunci yang sama mempunyai tarikh yang lebih lewat.
Pendekatan ini berfungsi tetapi menjalankan pertanyaan dalaman bagi setiap baris, jadi lebih perlahan pada jadual besar dan kurang sesuai apabila berlaku seri. Nyatakannya untuk menunjukkan keluasan pengetahuan, tetapi utamakan jawapan fungsi tetingkap demi prestasi.
SELECT o.*
FROM orders o
WHERE o.order_date = (
SELECT MAX(o2.order_date)
FROM orders o2
WHERE o2.customer_id = o.customer_id
);Pintasan DISTINCT ON PostgreSQL
PostgreSQL menawarkan ungkapan ringkas: DISTINCT ON (key) mengekalkan baris pertama bagi setiap kunci mengikut ORDER BY. ORDER BY mesti bermula dengan lajur kunci yang sama, kemudian diikuti pemecah seri atau cap masa.
Ia kemas dan pantas dalam PostgreSQL, tetapi tidak mudah dipindahkan. Nyatakannya sebagai tambahan khusus dialek sambil mengekalkan ROW_NUMBER sebagai pilihan lalai yang mudah dipindahkan.
SELECT DISTINCT ON (customer_id)
customer_id, order_id, order_date, amount
FROM orders
ORDER BY customer_id, order_date DESC, order_id DESC;Baris Terkini dengan Syarat
Soalan sebenar menambah penapis: "pesanan selesai yang paling terkini bagi setiap pelanggan". Gunakan penapis sebelum pemeringkatan supaya hanya baris yang memenuhi syarat dinomborkan.
Letakkan syarat dalam WHERE bagi pertanyaan dalaman, kerana ia dijalankan sebelum fungsi tetingkap, kemudian ambil rn = 1 dalam pertanyaan luaran. Menapis selepas pemeringkatan akan memberikan baris yang salah.
WITH ranked AS (
SELECT *,
ROW_NUMBER() OVER (
PARTITION BY customer_id ORDER BY order_date DESC, order_id DESC
) AS rn
FROM orders
WHERE status = 'completed'
)
SELECT * FROM ranked WHERE rn = 1;Contoh Lengkap: Status Peranti Terkini
Jadual status_log merekodkan device_id, status dan logged_at. Untuk mendapatkan status semasa setiap peranti, bahagikan mengikut device_id, susun mengikut logged_at DESC, dan kekalkan rn = 1.
Inilah asas kepada papan pemuka yang menunjukkan "keadaan semasa" banyak entiti daripada log peristiwa yang hanya menerima penambahan. Resipi yang sama menggerakkan pertanyaan harga terkini, lokasi terkini dan versi terkini.
WITH latest AS (
SELECT device_id, status, logged_at,
ROW_NUMBER() OVER (
PARTITION BY device_id ORDER BY logged_at DESC
) AS rn
FROM status_log
)
SELECT device_id, status, logged_at
FROM latest
WHERE rn = 1;Nota Prestasi
Isi penting yang menunjukkan kemahiran lanjutan:
- Indeks pada
(customer_id, order_date DESC)membolehkan enjin membaca baris terkini bagi setiap kunci dengan cekap. - Pendekatan fungsi tetingkap mengimbas jadual sekali; subpertanyaan berkorelasi tidak berbuat demikian.
DISTINCT ONdalam PostgreSQL boleh menggunakan indeks yang sama dan selalunya merupakan pilihan terpantas untuk satu jadual.- Bagi log peristiwa yang banyak menerima penambahan, pertimbangkan jadual "terkini" yang terwujud dan disegarkan secara berperingkat.
Kesilapan Lazim
Berhati-hati dengan perkara ini:
- Menggunakan
MAX(date)dan mengembalikan tarikh sahaja, bukan keseluruhan baris. - Melupakan pemecah seri, lalu menghasilkan keputusan yang tidak tentu apabila tarikh seri.
- Menapis berdasarkan syarat selepas pemeringkatan, yang boleh memilih baris yang sepatutnya dikecualikan.
- Mengelirukan "satu baris terkini" (
ROW_NUMBER) dengan "semua baris terkini yang seri" (RANK).
Semakan Pantas
Pilih pertanyaan rekod terkini bagi setiap kunci yang betul.
Ringkasan: Rekod Terkini bagi Setiap Kunci
Coraknya: PARTITION BY kunci, ORDER BY cap masa DESC (serta pemecah seri unik), kekalkan rn = 1.
MAX(date)memberikan tarikh, bukan keseluruhan baris.- Sentiasa tambahkan pemecah seri untuk memastikan hasil yang konsisten.
- Gunakan
RANK() = 1jika anda mahukan semua baris yang seri pada cap masa terkini. - Syarat penapis hendaklah berada dalam pertanyaan dalaman, sebelum pemeringkatan.
DISTINCT ONPostgreSQL ialah alternatif khusus dialek yang ringkas dan pantas.
Pelajari Persediaan Temu Duga Pengaturcaraan dengan tutor kecerdasan buatan — percuma
Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.
- Kursus
- 90
- Pelajaran
- 360
Soalan Lazim
Adakah pelajaran “Mengekalkan Baris Terbaharu bagi Setiap Kunci” percuma?
Ya — teks penuh “Mengekalkan Baris Terbaharu bagi Setiap Kunci” boleh dibaca secara percuma di web ini. Untuk berlatih secara interaktif menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7, serta membuka kunci baki kursus Persediaan Temu Duga Pengaturcaraan, tingkat taraf kepada CoddyKit PRO. Kursus Persediaan Temu Duga Pengaturcaraan merangkumi sejumlah 4 pelajaran.
Apakah yang akan saya pelajari dalam “Mengekalkan Baris Terbaharu bagi Setiap Kunci”?
Corak “rekod paling terkini bagi setiap pelanggan” dengan partition mengikut kunci dan susunan mengikut tarikh Anda berlatih Persediaan Temu Duga Pengaturcaraan menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.
Adakah saya memerlukan pengalaman untuk memulakan Persediaan Temu Duga Pengaturcaraan?
Tiada pengalaman terdahulu diperlukan. Pembelajaran Persediaan Temu Duga Pengaturcaraan di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 4 daripada 4.
Berapa lamakah pelajaran “Mengekalkan Baris Terbaharu bagi Setiap Kunci” diambil?
Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.
Bolehkah saya menulis dan menjalankan kod dalam pelajaran Persediaan Temu Duga Pengaturcaraan ini?
Ya. Setiap pelajaran Persediaan Temu Duga Pengaturcaraan menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.
Semua pelajaran dalam kursus ini
- Baris Teratas-N Setiap Kumpulan Dengan ROW_NUMBER
- Mengendalikan Nilai Seri dalam Teratas-N
- Membuang Pendua Baris dengan Selamat
- Mengekalkan Baris Terbaharu bagi Setiap Kunci