Rumah >pangkalan data >tutorial mysql >Bagaimana untuk Menyelesaikan 'DISTINCT ON Expressions Must Match Initial ORDER BY Expressions' dalam PostgreSQL?

Bagaimana untuk Menyelesaikan 'DISTINCT ON Expressions Must Match Initial ORDER BY Expressions' dalam PostgreSQL?

Patricia Arquette
Patricia Arquetteasal
2025-01-21 12:22:14237semak imbas

How to Resolve

Klausa

PostgreSQL DISTINCT ON memudahkan mendapatkan semula baris pertama untuk setiap nilai unik dalam set. Walau bagaimanapun, perangkap biasa timbul apabila ungkapan DISTINCT ON tidak sejajar dengan ungkapan ORDER BY awal.

DISTINCT ON Ralat Tidak Padan Ungkapan

Ralat ini kerap berlaku:

<code class="language-sql">SELECT DISTINCT ON (address_id) purchases.address_id, purchases.*
FROM purchases
WHERE purchases.product_id = 1
ORDER BY purchases.purchased_at DESC</code>

Mengakibatkan:

<code>PG::Error: ERROR:  SELECT DISTINCT ON expressions must match initial ORDER BY expressions</code>

Penyelesaian: Menjajarkan DISTINCT ON dan ORDER BY

Dokumentasi PostgreSQL memberi mandat bahawa DISTINCT ON ungkapan mesti mencerminkan ungkapan ORDER BY paling kiri. Penyelesaiannya adalah mudah: susun semula klausa ORDER BY anda:

<code class="language-sql">SELECT DISTINCT ON (address_id) purchases.address_id, purchases.*
FROM purchases
WHERE purchases.product_id = 1
ORDER BY address_id, purchases.purchased_at DESC</code>

Kaedah Alternatif: Memintas address_id Memesan

Jika anda perlu mengelak membuat pesanan dengan address_id, pertimbangkan alternatif ini:

Kaedah 1: Pendekatan "N Terhebat setiap kumpulan"

Kaedah ini cekap mencari pembelian terbaharu untuk setiap address_id:

<code class="language-sql">SELECT t1.* 
FROM purchases t1
JOIN (
    SELECT address_id, max(purchased_at) as max_purchased_at
    FROM purchases
    WHERE product_id = 1
    GROUP BY address_id
) t2
ON t1.address_id = t2.address_id AND t1.purchased_at = t2.max_purchased_at
ORDER BY t1.purchased_at DESC</code>

Kaedah 2: Pertanyaan Bersarang untuk PostGreSQL

Pendekatan ini menggunakan subkueri untuk mencapai hasil yang diingini sambil mengekalkan purchased_at pesanan:

<code class="language-sql">SELECT * 
FROM (
  SELECT DISTINCT ON (address_id) *
  FROM purchases 
  WHERE product_id = 1
  ORDER BY address_id, purchased_at DESC
) t
ORDER BY purchased_at DESC</code>

Alternatif ini memberikan fleksibiliti apabila anda tidak mahu mengutamakan address_id dalam pesanan keluaran akhir. Mereka secara berkesan menangani masalah "pembelian setiap alamat terkini" tanpa langsung melanggar kekangan DISTINCT ON.

Atas ialah kandungan terperinci Bagaimana untuk Menyelesaikan 'DISTINCT ON Expressions Must Match Initial ORDER BY Expressions' dalam PostgreSQL?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn