2016-05-04 9 views
3

Ich versuche den Mindestpreis pro Reise zu erhalten und weiß, welche Reisedetails diesem Mindestpreis pro Reise entsprechen.Finden Sie den Mindestwert UND die korrekten Spaltenwerte

Dafür habe ich alle Arten von Variationen mit Unterabfragen, Joins usw. versucht, aber da es nicht 1 Primärschlüssel gibt, kann ich es nicht herausfinden.

Was ich versuche zu erreichen ist, die Reise mit dem niedrigsten Preis zu bekommen, und dann in der Aufzeichnung die Details der Reise mit diesem niedrigsten Preis enthalten.

SELECT travel_id, persons, days, MIN(`price`) AS `price` 
    FROM travel_details 
    WHERE 1 
    GROUP BY `travel_id` 
    HAVING MIN(price); 

Einfache Version meiner Tisch Spalten, Spalten sind: travel_id, persons, days, price

Diese Säulen bilden zusammen den Primärschlüssel.

Eine Reise kann für verschiedene Personen, Tage und Preise gebucht werden. Es kann auch vorkommen, dass mehrere Preisoptionen für dieselbe Kombination von travel_id, persons und days vorliegen.

Z. B.

100, 2, 4, **250** 

100, 2, 4, **450** 

100, 2, **5**, 450 

101, 2, 4, 190 

101, 2, 5, 185 

travel_id Sein 100 für 2 Personen für 4 Personen.

Was möchte ich erreichen möchte, ist Rückkehr: 100, 250, und dann mit richtigen entsprechenden Werte:

100, 2, 4, 250

101, 2, 5, 185

Jetzt mischt mein Ergebnis einfach alle anderen Daten. Wenn ich diese Spalten in die Gruppe mit einbeziehe, wird sie nicht mehr nur auf travel_id gruppiert, sondern beispielsweise auch auf persons. Dann werden alle Kombinationen für eine travel_id und persons zurückgegeben.

Irgendeine Idee, wie man das angeht?

+0

Meiner Meinung nach, haben Sie die falsche Antwort akzeptiert. Wenn die andere Antwort nicht für Sie funktioniert, deutet das eher auf einen Fehler in Ihrem Design als auf einen Fehler in dieser Lösung hin. – Strawberry

+0

Das könnte sein, aber mit einem solchen Kommentar dann bitte definieren, was der Fehler im Design ist. Eine normale Tabelle mit 4 Spalten, die alle eindeutig als Primärschlüsselspalten definiert sein müssen. Oder eine normale Tabelle mit 5 Spalten mit 1 UID-Spalte als Primärschlüsselspalte und 4 normalen Spalten mit den Werten. Wie ist eine solche grundlegende Tabelleneinrichtung ein Konstruktionsfehler? Die Frage ist, wie man pro Reise 1 vollen und korrekten Rekord mit dem niedrigsten Preis bekommt. Wie erhält man diesen 1 Datensatz pro Reise, wenn es mehrere Optionen pro Reise mit dem gleichen - niedrigsten - Preis gibt, aber z. B. 3 Personen anstelle von 4 Personen. – PeterH

+0

Für die "Aufnahme", bevor Sie Ihren Kommentar veröffentlicht haben, ergänzte ich die Antwort von Sagi. Mit dieser letzten "Gruppe durch" ist das Problem gelöst. Vielleicht hast du das nicht gesehen, überprüfe die Antwort unten. – PeterH

Antwort

0

Sie IN() verwenden können, dies zu tun:

SELECT * FROM travel_details t 
WHERE (t.travel_id,t.price) IN(SELECT s.travel_id,min(s.price) 
           FROM travel_details s 
           GROUP BY s.travel_id) 
GROUP BY t.travel_id; // this last group-by is to filter doubles when there are multiple records per travel with the lowest price. 
+0

Hallo Sagi, danke für die Antwort. Die Abfrage läuft auf meiner Beispieldatenbank mit nur 20K-Datensätzen für mehr als 3 Minuten, also habe ich sie abgebrochen. Es muss innerhalb von 1 Sekunde ausgeführt werden. Und mit mehreren einzelnen Abfragen kann ich das erreichen. Allerdings kann ich nicht glauben, dass es in mysql keine Option gibt, in der Tabelle den Datensatz mit dem niedrigsten Preis pro Gruppe auszuwählen. Irgendwelche anderen Ideen? – PeterH

+0

Ja, fügen Sie Indizes zu 'travel_id, price 'auf dem Tisch hinzu. Es dauert eine Sekunde mit 20k Datensätze @peterh – sagi

+0

Ich würde Ihnen zustimmen, aber alle Spalten sind Primärschlüssel, so dass sie bereits vollständig von der MySQL-Datenbank indiziert sind. Zweitens löst dies die Tatsache, die in der Antwort unten auf "undefinierte Variable" hingewiesen wird. Denken Sie, diese Abfrage wird auch mehrere Datensätze pro Reise zurückgeben, wenn es mehrere Optionen mit dem niedrigsten Preis gibt, z. B. mit 3 Personen 200 EUR und auch Option mit 4 Personen für 200 EUR. Wie man es löst, so dass es nur einen Datensatz pro Reise auswählt. Oder ist es einfach nicht möglich. – PeterH

1
Select a.travel_id, a.persons, a.days, a.price from travel_details a 
JOIN (Select travel_id,MIN(Price) as p from travel_details group by travel_id) b 
on b.travel_id=a.travel_id and b.p=a.price 

Die obige Abfrage verwendet Self Join. Abgeleitete Tabelle b enthält travel_id zusammen mit min-Preis.

+0

Hallo "undefined_variable", danke für die Antwort. Diese Art von Lösung hatte ich auch mit einer Unterabfrage. Was jedoch passiert ist, dass es mehrere Ergebnisse pro Gruppe ergeben wird. Zum Beispiel: travel_id = 102, in Datensatz # 1 Personen = 3 und in Datensatz # 2 Personen = 4, beide kosten beispielsweise 200 EUR. Die obige Abfrage gibt beide Datensätze für diese travel_id = 102 zurück. Es ist nicht möglich, "personen" zur Auswahlzeichenfolge der Join-Abfrage hinzuzufügen und daher auch nicht zur main select-Abfrage hinzuzufügen "b.price = a .Preis AND b.persons = a.persons ". – PeterH

Verwandte Themen