2015-06-23 14 views
5

Ich schreibe eine Abfrage, um alle Spieler für alle Teams zu bekommen. Anstatt die Anwendung zu durchlaufen, entschied ich mich, die Spieler aller Teams unter array_agg() in eine einzige Abfrage zu bringen. Ich habe die Abfrage wie folgt geschrieben: (. Genau das nicht der Spieler)Zurück erstes Element in array_agg()

SELECT team_id, array_agg(team_name) AS teamname, 
     array_agg(player_id||'##'||player_name) AS playerdetails 
FROM team 
INNER JOIN players ON team_id = player_team 
GROUP BY team_id 

Diese Abfrage gibt mir das Ergebnis, wie unten in der Folge die teamname gesetzt wird wiederholt

team_id    team_name                 playerdetails 
1  {Australia,Australia,Australia,Australia}      {"5##Glenn Donald McGrath","6##Shane Warne","2##Steve Waugh","1##Adam Gilchrist"} 
2  {India,India,India,India}          {"8##Kapil Dev","11##Saurav Ganguly","3##Rahul Dravid","9##Sachin Tendulkar"} 
3  {"South Africa","South Africa","South Africa","South Africa"} {"12##Gary Kristen","4##Shaun Pollock","7##Jacques Kallis","10##Alan Donald"} 

Ist es eine Möglichkeit, das Ergebnis wie dies

team_id    team_name                 playerdetails 
1     Australia      {"5##Glenn Donald McGrath","6##Shane Warne","2##Steve Waugh","1##Adam Gilchrist"} 

ich es erreicht habe, zurückzukehren, um eine Unterabfrage, sondern will wissen, ob ihre möglich, sie ohne die Unterabfrage zu schreiben

SELECT team_id, teamname[1], playerdetails 
FROM (
    SELECT team_id, array_agg(team_name) AS teamname, 
     array_agg(player_id||'##'||player_name) AS playerdetails 
    FROM team 
    INNER JOIN players ON team_id = player_team 
    GROUP BY team_id) AS tempresult 

Die sqfiddle ist hier. Und ich bin mit Postgresql 8,4

[EDIT]
ich tatsächlich wurde von Hack auf die GROUP BY Einschränkung denken column "team.team_status" must appear in the GROUP BY clause or be used in an aggregate function, wenn versuchen, die eine Spalte abzurufen, die in der Gruppe nicht von

angegeben wurde
SELECT team_id, array_agg(team_name) AS teamname, 
     array_agg(player_id||'##'||player_name) AS playerdetails, 
     team_status -- could be replaced by something like array_agg(team_status)[0] or customfunction(team_status) 
FROM team 
INNER JOIN players ON team_id = player_team 
GROUP BY team_id 
+0

Ich denke, man kann dies nützlich finden: http://stackoverflow.com/questions/3994556/eliminate-duplicate-array-values-in-postgres –

+0

Warum wollen Sie es ohne Unterabfrage tun wollen ? – Patrick

+0

@Patrick Zuerst die Frage basiert auf etwas Neugier, ich habe versucht, es ohne viel Erfolg zu tun .. und ich denke, die Verwendung von Unterabfrage wird weniger effizient sein, wenn große und komplexe Abfragen auf große Datensätze –

Antwort

3

ganz einfach, nicht aggregieren die team_name aber GROUP BY es:

SELECT team_id, team_name, array_agg(player_id||'##'||player_name) AS playerdetails 
FROM team 
JOIN players ON team_id = player_team 
GROUP BY team_id, team_name; 
+0

Ich habe nicht wirklich daran gedacht , nice suggestion ... aber die Tatsache ist, dass es mehr Tabellen zu verbinden gibt und mehr Auswahlspalten –

+0

Auch ich erwarte eine generische Funktion/Implementierung, die in anderen Abfragen auch verwendet werden kann. –

+2

Die obigen Antworten genau Ihre Frage, Sie kann Ihr eigenes SQLFiddle einchecken. Natürlich kann ich keine Dinge beantworten, nach denen du nicht gefragt hast. Also editiere deine Frage oder poste eine neue Frage. Was meinen Sie zum Beispiel mit "generische Funktion/Implementierung"? – Patrick

1

es war eigentlich ein mis nimm meinen teil ... die antwort auf meine erste frage liegt in dieser frage selbst. Ich muss nur die (array_agg(team_name))[1] beilegen, früher habe ich es ohne die Klammern versucht.

SELECT team_id, (array_agg(team_name))[1] AS teamname, 
    array_agg(player_id||'##'||player_name) AS playerdetails 
FROM team 
INNER JOIN players ON team_id = player_team 
GROUP BY team_id 
Verwandte Themen