Die Wahl von max() für mehrere Spalten
Ok, hier ist meine Tabelle:
product_id version_id update_id patch_id
1 1 0 0
1 1 1 0
1 1 1 1
1 1 2 0
1 1 2 1
2 1 0 0
2 2 0 0
2 3 0 0
2 3 0 1
3 1 0 0
3 1 0 1
Nun möchte ich wählen Sie die neueste version von einem Produkt, also die version mit der höchsten update_id & patch_id.
Beispielsweise die neueste version von
- Produkt 1 sollten zurück 1, 2, 1
- Produkt 2 zurückkehren sollte, 3, 0, 1
- Produkt 3 zurückkehren sollte, 1, 0, 1
Ich versuchte alle Arten von Sachen, die mit GROUP BY und HAVING, versuchte Unterabfragen, aber ich kann immer noch nicht herausfinden, einen Weg, dies zu erreichen.
Kann mir jemand helfen den richtigen zu finden-Abfrage, oder sollte ich schreiben eine php-Funktion dafür?
Bearbeiten
Einige zusätzliche Infos:
- Die Spalten sind zusammen der Primärschlüssel (es sind mehr Spalten, aber für dieses problem Sie nicht betrifft)
- Keine der Spalten ist auto-increment
Dies ist die Tabelle:
CREATE TABLE IF NOT EXISTS `db`.`patch` (
`product_id` INT NOT NULL ,
`version_id` INT NOT NULL ,
`update_id` INT NOT NULL ,
`patch_id` INT NOT NULL
PRIMARY KEY (`product_id`, `version_id`, `update_id`, `patch_id`) ,
INDEX `fk_patch_update1` (`product_id` ASC, `version_id` ASC, `update_id` ASC) )
Edit 2
Gekennzeichnet als Duplikate, es ist nicht: Die andere Frage scheint für Datensätze, die höher als ein Wert für jeden der drei verschiedenen Spalten.
In dieser Frage suchen wir nach der höchsten Versionsnummer gruppiert nach product_id.
Edit 3
landesvermessungsamtes Antwort sagt mir wieder, dass dies ein Duplikat ist. Zunächst einmal: diese Frage ist älter. Zweitens, ich glaube nicht, dass die Antwort ist die gleiche.
landesvermessungsamtes schlägt mit der folgenden Abfrage:
SELECT product_id, GREATEST(version_id, update_id, patch_id) AS latest_version FROM patch.
GRÖßTEN(1,2,3) liefert 3, richtig? Wat, wenn wir diese Werte:
product_id version_id update_id patch_id
1 1 0 0
1 1 2 8
1 3 0 0
So wie ich das verstehe, ist diese Abfrage wil zurück:
product_id latest_version
1 1
1 8
1 3
Aber es sollte zurück:
product_id version_id update_id patch_id
1 3 0 0
Ich glaube nicht, GRÖßTEN helfen könnte. Wenn Sie denken, es wird, bitte beweisen mich nicht falsch.
Mögliche Duplikate von Mysql-max-Wert aus 3 verschiedenen Spalten
Dies ist kein Duplikat. Siehe mein edit.
Zu klären ist, ist die Bedingung, dass die Rückgabe von Zeilen muss die höchste patch_id der höchsten update_id des höchsten version_id jeder product_id?
Ja, das ist die Bedingung.
InformationsquelleAutor Scuba Kay | 2011-12-14
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dies ist ein Beispiel, wenn eine eindeutige identifers nützlich sein können.
Stellen Sie sich vor Sie haben eine autoincrememnting ID-Feld, dann können Sie die id für jedes Produkt über eine korrelierte sub-query...
Den Gegenwert ohne eine eindeutige Bezeichner erfordert mehrere korrelierte sub-queries...
Diese wäre deutlich langsamer als auf einer Tabelle mit einem eindeutigen identifier-Spalte.
Andere alternative (ohne unique identifier) ist self-join auf verschiedenen Ebenen der aggregation.
patch_id
btw (es ist nicht eine, die groß genug ändern, SO wird mir erlauben, zu Bearbeiten)danke, korrigiert 🙂
Was passiert, wenn diese Zeile in der Tabelle (1,1,1,3) ?
Mit der auto-increment-ID-Feld, jede Zeile hat eine eindeutige Kennung. Dann ist die sub-Abfrage findet alle Datensätze, die für die zugeordnete product_id. Dann, wird nur das erste ausgewählt wird (höchste Version, Update, Patch). Dann die äußere query holt die Datensätze mit eindeutiger id. Kurz gesagt, es funktioniert immer noch, was auch immer Werte, die Sie haben.
Habe vergessen zu sagen, keine der Spalten ist auto-increment. Der primäre Schlüssel ist, product_id, version_id, update_id und patch_id zusammen. Also, in meinem Fall, dies wird nicht helfen, oder?
InformationsquelleAutor MatBailie
Versuchen:
Entschuldigen Sie mich, es ist @RolandoMySQLDBA. Verzeihen Sie die Störung, aber ich bin Entsendung Ihrer Abfrage, und Ihre Ausgabe gegen die Beispieldaten:
Deine Abfrage funktioniert, wie dargestellt. Es ist auch einfacher als meine Antwort. Gute Show!!!!!
Dies scheint zu funktionieren, @Dems In newbie-Sprache, was ist Ihr problem mit diesem Ansatz?
Ich dachte, ich hätte gelesen, dass MySQL die Werte aus dem ersten Datensatz in der Gruppe (geordnet nach index, wenn keine überwiegenden Sortierreihenfolge angegeben ist; die order by-Klauseln mit oder nach der Gruppe werden nur übernommen, nachdem die Gruppierung), aber ich finde keine Quellenangabe für diese. Im Gegensatz dazu, die MySQL-Referenz-Handbuch, im Abschnitt über "die GROUP BY-und HAVING mit Ausgeblendeten Spalten", die explizit sagt, dass der nicht-gruppierten Spalten, dass "das Ergebnis ist unbestimmt".
Dems ist besorgt, dass dieser Ansatz möglicherweise nicht zuverlässig, auch wenn es funktioniert unter Testbedingungen.
Ich bin überrascht. Ich habe versucht die Abfrage der Beispiel-Daten in meine Frage UND DEINE ABFRAGE FUNKTIONIERT !!! + 1 !!!
InformationsquelleAutor
Habe ich nicht getestet, aber ich bin sicher, Sie können etwas tun, wie dieses
Entschuldigen Sie mich, es ist @RolandoMySQLDBA. Verzeihen Sie die Störung, aber ich bin Entsendung Ihrer Abfrage, und Ihre Ausgabe gegen die Beispieldaten:
Obwohl die Anzeige unterschiedlich ist, wird die Abfrage logisch arbeitet für die ursprüngliche Frage. +1 von mir !!!
InformationsquelleAutor Fred
Könnten Sie durch
max(update_id * maxpatchidvalue + patch_id)
zu bekommen, was Sie wollen.das ist richtig
assuminga max_patch_id von 100 : (2 * 100 + 0) > (1 * 100 + 1) => dieser Mechanismus funktioniert, vorausgesetzt, dass es nicht zu einem überlauf-Fehler.
InformationsquelleAutor fge
Verwenden Sie Ihre Eingabedaten von der Frage, und eine Tabelle ohne Schlüssel, hier ist ein ziemlich krankes Konzept, das funktioniert:
Zunächst die Abfrage, die Sie brauchen, ist diese:
Ist hier einige Beispiel-code mit allen zahlen, nicht Indizes und Ihrer Daten Beispiel:
Hier ist das Ergebnis:
Probieren Sie es aus !!!
VORBEHALT
Meine Antwort wird die Unterstützung pro Produkt
Die Formel ist anders. Ich benutze
version_id*10000+update_id*100+patch_id
. @fge verwendetupdate_id * maxpatchidvalue + patch_id
Meine Antwort erzeugt die gewünschte Ausgabe auf der Grundlage der input-Daten, die in die Frage.
InformationsquelleAutor RolandoMySQLDBA
Versuchen.
Gute Punkte, ich habe überarbeitet.
InformationsquelleAutor Glenn
MySQL hat die
GREATEST
- Funktion, so sollten Sie es verwenden, wie diese:Markierte ich diese Frage als Duplikat, weil beide Fragen sind im Grunde Fragen, die gleiche Sache, die Auswahl der maximale Wert der verschiedenen Spalten. Hier verwenden Sie in der SELECT-Klausel, in der anderen Frage, die Sie verwenden Sie in der WHERE-Klausel. In jedem Fall GRÖßTE der trick funktioniert.
GRÖßTE(1,2,3) liefert 3, richtig? Wat, wenn wir diese Werte: version_id product_id update_id patch_id 1 1 0 0 1 1 2 8 1 3 0 0 so Wie ich das verstehe, wird die Abfrage wil zurück: product_id latest_version 1 1 1 8 1 3, Aber es sollte zurück: version_id product_id update_id patch_id 1 3 0 0
> Sie markiert diese Frage als Duplikat eine Frage, die ein Jahr jünger durch die Art, wie < habe ich? So what? Ich bin nur versuchen, zu reduzieren die Anzahl der redundanten Fragen, die ich gar nicht denken, der Dauer der Betriebszugehörigkeit.
InformationsquelleAutor rgz