Heim >Datenbank >MySQL-Tutorial >Wie löse ich „DISTINCT ON-Ausdrücke müssen mit anfänglichen ORDER BY-Ausdrücken übereinstimmen' in PostgreSQL?

Wie löse ich „DISTINCT ON-Ausdrücke müssen mit anfänglichen ORDER BY-Ausdrücken übereinstimmen' in PostgreSQL?

Patricia Arquette
Patricia ArquetteOriginal
2025-01-21 12:22:14157Durchsuche

How to Resolve

Die DISTINCT ON-Klausel von PostgreSQL vereinfacht das Abrufen der ersten Zeile für jeden eindeutigen Wert innerhalb einer Menge. Eine häufige Gefahr entsteht jedoch, wenn der DISTINCT ON-Ausdruck nicht mit dem anfänglichen ORDER BY-Ausdruck übereinstimmt.

DISTINCT ONAusdruckskonfliktfehler

Dieser Fehler tritt häufig auf:

<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>

Ergebnis:

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

Die Lösung: DISTINCT ON und ORDER BY

ausrichten

Die Dokumentation von PostgreSQL schreibt vor, dass die DISTINCT ON-Ausdrücke die am weitesten links stehenden ORDER BY-Ausdrücke widerspiegeln müssen. Die Lösung ist einfach: Ordnen Sie Ihre ORDER BY-Klausel neu:

<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>

Alternative Methoden: Umgehen der address_idBestellung

Wenn Sie eine Bestellung bis address_id vermeiden möchten, ziehen Sie diese Alternativen in Betracht:

Methode 1: Der „Größte N pro Gruppe“-Ansatz

Diese Methode findet effizient den letzten Kauf für jeden 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>

Methode 2: Verschachtelte Abfrage für PostGreSQL

Dieser Ansatz verwendet eine Unterabfrage, um das gewünschte Ergebnis zu erzielen und gleichzeitig die purchased_at Reihenfolge beizubehalten:

<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>

Diese Alternativen bieten Flexibilität, wenn Sie address_id bei der endgültigen Ausgabereihenfolge keine Prioritäten setzen möchten. Sie lösen effektiv das Problem des „letzten Kaufs pro Adresse“, ohne direkt gegen die DISTINCT ON-Einschränkung zu verstoßen.

Das obige ist der detaillierte Inhalt vonWie löse ich „DISTINCT ON-Ausdrücke müssen mit anfänglichen ORDER BY-Ausdrücken übereinstimmen' in PostgreSQL?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn