2017-04-07 2 views
0

Ich habe eine Anfrage in Sqlalchemy mit SQLite, die ein Objekt der Gruppe zurück mit und Wert (Durchschnitt):erstes Objekt der Gruppe von in postgresql/sqlalchemy

result = session.query(
     obj, func.avg(obj.value).label("value_avg") 
    ).group_by(
     func.strftime('%s', obj.date) 
    ).all() 

Aber jetzt brauche ich postgresql zu verwenden Das ist restriktiver (striktes SQL) und ich muss das gleiche tun, aber es muss die Abfrage (obj) durch etwas in der Gruppe durch like func.avg() oder etwas anderes ersetzen. Also würde ich gerne wissen, ob es irgendwelche Funktionen gibt, die das erste Objekt jeder Gruppe zurückgeben können. Falls dies nicht möglich Vielleicht kann ich Komparator für meine obj implementieren und zum Beispiel Call func.min (obj) wie folgt aus:

result = session.query(
     func.min(obj), func.avg(obj.value).label("value_avg") 
    ).group_by(
     func.date_part('second', obj.date) 
    ).all() 

Und vielleicht cmp und eq in meinem obj Modell implementieren? (Was ist die beste Praxis)

EDIT:

ich eine Abhilfe bekam aber ich bin nicht sicher, dass es eine gute Praxis. Erste Gruppe von und im nächsten kommen:

sq = session.query(
     func.min(obj.date).label("date"), func.avg(obj.value).label("value_avg") 
    ).group_by(
     func.cast(func.extract('second', obj.date)/600, Integer) 
    ).order_by(obj.date).subquery() 
result = session.query(obj, sq.c.value_avg).join(sq,sq.c.date == obj.date).all() 

Was ich will, ist die erste obj jeder Gruppe und value_avg der Gruppe

+0

Ihre Lösung (allgemein) könnte mehrere Ergebnisse zurückgeben. Es sei denn, der Wert in 'min()' ist eindeutig (was ich denke, weil "id" wie ein Primärschlüssel klingt; aber wenn es nur ein Fremdschlüssel ist, ist das vielleicht nicht der Fall). - Dies ist ein spezieller Fall von [Tag: Größte-N-pro-Gruppe] (wobei N = 1). Es gibt eine Menge von SQL-Lösungen bereits hier auf SO, aber ich weiß nicht, welche ist am besten geeignet für [SQLAlchemy] (http://stackoverflow.com/questions/tagged/sqlalchemy+greatest-n-per-group) . – pozs

+0

Sorry, ich bearbeite die ID zu Datum und Datum ist der Index so einzigartig. – Timo

+0

aber das macht wenig Sinn, denn 'SELECT min (Datum) ... GROUP BY date' und' SELECT date ... GROUP BY date' sind gleich (es gibt nur ein 'date' im' date 'Gruppe sowieso). - Ein einzelner Index garantiert auch nicht seine Einzigartigkeit. – pozs

Antwort

1

Sie müssen alle Spalten aufzulisten, die Sie auswählen möchten und sie in group_by setzen. Dann können Sie aggregierte Spalten auswählen, die nicht zur Gruppe gehören.

result = session.query(
    obj.column1, 
    obj.column2, 
    obj.column3, 
    func.strftime('%s', obj.date), 
    func.avg(obj.value).label("value_avg") 
).group_by(
    obj.column1, 
    obj.column2, 
    obj.column3, 
    obj.date 
).all() 
+0

Ja, aber es ist nicht einfach, wenn Sie mit einem Objekt wie obj.obj2.obj3 mit Lazy Query umgehen müssen – Timo

Verwandte Themen