GROUP BY - Aggregat : nur eindeutige Werte

KevinT

Neuer Benutzer
Beiträge
3
Hallo,
ich suche nach einem GROUP BY Aggregat, dass den Wert ausgibt, wenn dieser in der Gruppe eindeutig ist und ihn ignoriert, wenn es mehrere gibt.
Zur Veranschaulichung folgendes Beispiel:
1652786853176.png

Danke,
Kevin
 
Werbung:
1. Bitte keine Bilder, die lassen sich immer so schlecht via Copy&Paste in eine eine Tabelle pressen
2. gibt es dazu auch eine Frage, oder ist das nur eine Erfolgsstory?
 
Hrm, vielleicht lautet die nicht gestellt Frage, wie Du nur den Datensatz für bicycle bekommst...

Code:
postgres=# select * from rides ;
    ride    | weight | owner  | wheels 
------------+--------+--------+--------
 scateboard |    3.5 | john   |      4
 bicycle    |   25.4 | john   |      2
 motobike   |  120.6 | adam   |      2
 scateboard |    4.2 | britta |      4
 motobike   |  200.1 | adam   |      2
 scateboard |    3.1 | john   |      4
 scateboard |    5.5 | britta |      4
 motobike   |  150.5 | adam   |      3
 scateboard |    2.1 | britta |      4
(9 rows)

postgres=# with x as (select ride, avg(weight), count(distinct owner) o, count(distinct wheels) w from rides group by ride) select ride, avg from x where o+w=2;
  ride   |         avg         
---------+---------------------
 bicycle | 25.4000000000000000
(1 row)

postgres=#
 
Hi,
sorry, die korrekte Frage lautet: Wie komme ich vom Datensatz (oben) zum Ergebnissatz (unten).
Die Idee wäre ein GROUP BY-Query mit einer geheimnisvollen Aggregat-Funktion (bei mir CHECK genannt).

Zur Erläuterung des unteren Ergebnissatzes:
Wenn nach "rides" gruppiert wird, dann kann für Feld "owner" nur für bicycle (John) und für motobike (Adam) ein eindeutiger owner gefunden werden. Dieser soll dann auch angezeigt werden. Für scateboard gibt es mehrere owner (john, britta), daher soll hier NULL kommen.
Gleiche Logik für das numerische Feld wheels.

Hoffe das wird nun ein bisschen klarer.

Gruß,
Kevin
 
Wenn ich das richtig sehe soll bei einer Gruppierung auf ride z.B. in der Spalte owner nur dann ein Wert angegeben werden wenn kein anderer Wert existiert. Ich würde es mal so versuchen (ungetestet):
Code:
SELECT    ride,
    avg(weight) AS weight,
    owner
FROM    rides
GROUP BY ride,owner
HAVING count(owner) = count(DISTINCT owner)
UNION ALL
SELECT    ride,
    avg(weight) AS weight,
    NULL AS owner
FROM    rides
GROUP BY ride
HAVING count(owner) != count(DISTINCT owner)
Falls es nicht mit HAVING zu lösen ist könnte man es auch noch ohne Aggregat mit einem Subselect machen.

PS: wheels habe ich aus vereinfachungsgründen außen vor gelassen, das macht die Sache natürlich komplexer da sich ja nicht zwingend beide unterscheiden müssen.
 
Hi,
sorry, die korrekte Frage lautet: Wie komme ich vom Datensatz (oben) zum Ergebnissatz (unten).
Die Idee wäre ein GROUP BY-Query mit einer geheimnisvollen Aggregat-Funktion (bei mir CHECK genannt).

Zur Erläuterung des unteren Ergebnissatzes:
Wenn nach "rides" gruppiert wird, dann kann für Feld "owner" nur für bicycle (John) und für motobike (Adam) ein eindeutiger owner gefunden werden. Dieser soll dann auch angezeigt werden. Für scateboard gibt es mehrere owner (john, britta), daher soll hier NULL kommen.
Gleiche Logik für das numerische Feld wheels.

Hoffe das wird nun ein bisschen klarer.

Gruß,
Kevin
okay

Code:
postgres=# with x as (select ride, avg(weight), count(distinct owner) o, max(distinct owner) mo, count(distinct wheels) w, max(distinct wheels) mw  from rides group by ride) select ride, avg, case when o=1 then mo else null end as owner, case when w=1 then mw else null end as wheels from x ;
    ride    |         avg          | owner | wheels 
------------+----------------------+-------+--------
 bicycle    |  25.4000000000000000 | john  |      2
 motobike   | 157.0666666666666667 | adam  |       
 scateboard |   3.6800000000000000 |       |      4
(3 rows)

postgres=#
 
Hmm, vielleicht verstehe ich ja was nicht, aber das lässt sich doch mit einem CASE Ausdruck erreichen:

Code:
select ride, 
       avg(weight) as weight, 
       case
         when count(distinct owner) = 1 then max(owner)
         else null
       end as owner, 
       case
         when count(distinct wheels) = 1 then max(wheels)
         else null
       end as wheels
from rides
group by ride       
order by ride;
 
Werbung:
Zurück
Oben