2012-04-09 6 views
2

Ich habe eine Tabelle, Tabelle 1. In dieser Tabelle ist Name, Stadt, Preis. Die Namen sind alle einzigartig, die Städte können wiederverwendet werden. Ich möchte eine Abfrage erstellen, die mir den höchsten Preis jeder Stadt und den mit dieser Zeile verknüpften Namen gibt. Um den höchsten Preis für jede Stadt zu bekommen, mache ich nur:Gibt es eine Möglichkeit, dies in einer SELECT-Anweisung zu tun? Verwenden von Group By

SELECT MAX(price), city FROM table1 GROUP BY city 

Aber ich möchte den Namen auch. Wenn ich versuche

SELECT MAX(price), city, name FROM table1 GROUP BY city 

Dann bekomme ich nur einen Abfragefehler darüber, wie der Name nicht in der Gruppe enthalten ist. Wenn ich der Gruppe Namen hinzufüge, dann tut es nicht, was ich will. Ich kann mir vorstellen, wie ich das mit zwei Abfragen machen könnte, aber ich wette, es gibt einen Weg, es in nur einem zu tun. Was vermisse ich?

Ich habe ein paar ähnliche Fragen zu stackoverflow gefunden, aber alle scheinen etwas komplizierter zu tun, als ich versuche. Ich habe immer nur einfache SQL-Abfragen verwendet, so dass ich mich über einige der fortgeschritteneren Funktionen informiere.

Antwort

4
WITH RankedPrices AS (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY city ORDER BY price DESC) AS ix 
    FROM table1 
) 
SELECT * FROM RankedPrices WHERE ix=1; 

Beachten Sie, dass Sie nicht angegeben haben, was beide, wenn zwei Produkte in einer Stadt passieren sollte die teuerste und gleich in ihren Preis. Diese Abfrage gibt hier einen der beiden (aber nur einen) zurück, Sie könnten dies auch anders handhaben.

+0

Ja, das scheint zu mir zurück zu kommen, nicht genau zu wissen, was ich will (oder genauer, eine alte Datenbanktabelle verwendend, um einige neue Abfragen auszuprobieren). Die anderen Antworten geben mir Wiederholungen. Ich verstehe nur irgendwie, wie Ihre Abfrage funktioniert, aber an einem Tag sollte ich es haben. Thanks – cost

+0

Ich teile die Abfrage in zwei Schritten: zuerst richte ich die durch die Stadt partitionierten Preise in der "virtuellen Tabelle" ein (der Name für dieses Konstrukt ist ein [Common Table Expression] (http://msdn.microsoft.com/en- us/library/ms190766.aspx)), so dass ich weiß, welches das teuerste Item nach seinem Rang ist ('ix'). Ich filtere danach. Wenn Sie also die ersten drei teuersten Namen pro Stadt haben wollten, könnten Sie einfach 'ix <= 3 'in der where-Klausel verwenden. Oder wenn Sie eine andere Rangfolge wünschen, verwenden Sie einfach eine andere [ranking functions] (http://msdn.microsoft.com/en-us/library/ms189798.aspx), die von SQL Server anstelle von 'ROW_NUMBER' bereitgestellt wird. – Lucero

+0

Ich verstehe, könnte ich ein paar Fragen im Chat stellen? – cost

1
SELECT 
    name, city, price 
FROM 
    table1 t 
WHERE 
    price = (SELECT MAX(price) FROM table 1 WHERE city = t.city) 

Ein Index über (city, price) und über (price) hilft, die Leistung dieser Abfrage, wenn viele Zeilen sind.

1
SELECT name, city, price 
FROM table1 t 
WHERE price = (SELECT MAX(price) FROM table1 WHERE city = t.city) 
+0

Das hat funktioniert, irgendwie. Es gibt mir mehrere Reihen mit der gleichen Stadt, wenn die Preise gleich sind. Ich schätze, die Gruppe gibt dir nur die erste? Ich bin mir nicht ganz sicher, wie Ihre Abfrage das tut, was sie tut. Wird der Preis für jede Stadt oder etwas neu berechnet? Offensichtlich (SELECT MAX (Preis) FROM Tabelle1 WHERE Stadt = t.city) gibt nicht nur eine einzelne Zahl zurück, aber ich bin mir nicht sicher, wie – cost

+0

@cost, das Problem mit 'GROUP BY' ist, dass es aggregiert, so dass Es berechnet etwas aus mehreren Zeilenwerten, aber Sie wissen nicht, was die ursprünglichen Zeilen waren. Das ist der Grund, warum keine der hier verwendeten Lösungen 'GROUP BY' verwendet hat (obwohl der konzeptionell gleiche Ansatz wie für dieses Beispiel durch Verwendung eines' JOIN' in einer 'GROUP BY'-verschachtelten Abfrage erreicht werden konnte). – Lucero

+0

@kosten, ja, der Preis wird für jede Stadt neu berechnet. Die Abfrage findet den Namen und die Stadt, wo der Preis für diese bestimmte Stadt maximal ist. Geben die mehreren Zeilen denselben Namen zurück? Oder nur die selbe Stadt? –

1

Nur der Vollständigkeit halber, hier ist eine Probe GROUP BY verwenden, aber mit den gleichen Einschränkungen wie die anderen Lösungen von Tomalak und Logan in Bezug Handhabung doppelte max Preise pro Stadt:

SELECT t2.city, t2.name, t2.price 
    FROM (SELECT city, MAX(price) AS price FROM table1 GROUP BY city) AS t 
    JOIN table1 AS t2 ON t.city = t2.city AND t.price = t2.price 

ziehe ich das Ranking Ansatz, weil es klarer und viel flexibler ist.

Verwandte Themen