2016-08-03 16 views
3

Benutzer Tabelle mit folgenden Feldern.wählen Sie mehrere Spalten mit unterschiedlichen Bedingungen

id 
agent_id 
locality 
total 
building_type 
price 

Ich erhalte unterschiedliche Statistiken führen mit folgenden Abfragen

SELECT agent_id, COUNT(*) AS stat_1 
FROM users 
WHERE "building_type" = 'single' 
AND ("price" BETWEEN 0 AND 200000) 
GROUP BY "agent_id" 
order by agent_id 

SELECT agent_id, COUNT(*) AS stat_2 
FROM users 
WHERE "building_type" = 'single' 
AND ("price" BETWEEN 200001 AND 350000) 
GROUP BY "agent_id" 
order by agent_id 

SELECT agent_id, COUNT(*) AS stat_3 
FROM users 
WHERE "building_type" = 'single' 
AND ("price" BETWEEN 3500001 AND 500000) 
GROUP BY "agent_id" 
order by agent_id 

Aber ich will für alle Statistiken in derselben Abfrage Ergebnis erhalten wie

SELECT agent_id, 
     COUNT(*) AS stat_1, 
     COUNT(*) AS stat_2, 
     COUNT(*) AS stat_3 
from users 
where <Conditions> 

Wie ich dieses Ergebnis bekommen kann in eine Abfrage?

Antwort

3

Sie können bedingte Aggregation verwenden:

SELECT agent_id, 
     COUNT(*) filter (where price BETWEEN 0 AND 200000) as stat_1, 
     COUNT(*) filter (where price BETWEEN 200001 AND 350000) AS stat_2, 
     COUNT(*) filter (where price BETWEEN 3500001 AND 500000) AS stat_3 
from users 
WHERE building_type = 'single' 
GROUP BY agent_id 
order by agent_id 
+0

Danke für Antwort. Für mich geht das. –

3

Postgres 9.4 diese Art von Problemen in einer eleganten Art und Weise löst durch Zugabe einer filter-Klausel, die Sie eine Bedingung auf Aggregatfunktionen anwenden können:

SELECT agent_id, 
     COUNT(*) FILTER (WHERE "price" BETWEEN 0 AND 200000) AS stat_1, 
     COUNT(*) FILTER (WHERE "price" BETWEEN 200001 AND 350000) AS stat_2, 
     COUNT(*) FILTER (WHERE "price" BETWEEN 3500001 AND 500000) AS stat_3 
FROM  users 
WHERE "building_type" = 'single' 
GROUP BY "agent_id" 
ORDER BY "agent_id" 

Mit früheren Versionen, die eine filter-Klausel nicht zulassen, können Sie dasselbe Verhalten selbst implementieren, indem Sie die Aggregatfunktion auf einen Ausdruck case anwenden. Hier nutzen wir count ‚s-Eigenschaft des Ignorierens null s:

SELECT agent_id, 
     COUNT(CASE WHEN "price" BETWEEN 0 AND 200000 THEN 1 END) AS stat_1, 
     COUNT(CASE WHEN "price" BETWEEN 200001 AND 350000 THEN 1 END) AS stat_2, 
     COUNT(CASE WHEN "price" BETWEEN 3500001 AND 500000 THEN 1 END) AS stat_3 
FROM  users 
WHERE "building_type" = 'single' 
GROUP BY "agent_id" 
ORDER BY "agent_id" 
+0

Danke für Ihre Antwort. Ich denke, Ihre Antwort ist auch richtig, aber für meine Anforderung nur Filterklausel ist Arbeit. –

Verwandte Themen