How can I group by day and transpose output of a query in postgresql

1

I have a problem, I have tried to create a query that adds up the total values of a sensor grouped by day. I have tried a thousand ways and I can not, someone can help me?

A small example of the data I have:

Day value cod_sensor hour
06/12/2016 85 SENSOR1 0:05:00
06/12/2016 10 SENSOR1 0:10:00
06/12/2016 25 SENSOR1 0:15:00
06/13/2016 26 SENSOR1 0:05:00
06/13/2016 87 SENSOR1 0:10:00
06/13/2016 42 SENSOR1 0:15:00
06/12/2016 44 SENSOR2 0:05:00
06/12/2016 53 SENSOR2 0:10:00
06/12/2016 12 SENSOR2 0:15:00
06/13/2016 29 SENSOR2 0:05:00
06/13/2016 95 SENSOR2 0:10:00
06/13/2016 38 SENSOR2 0:15:00
06/12/2016 61 SENSOR3 0:05:00
06/12/2016 50 SENSOR3 0:10:00
06/12/2016 15 SENSOR3 0:15:00
06/13/2016 18 SENSOR3 0:05:00
06/13/2016 33 SENSOR3 0:10:00
06/13/2016 72 SENSOR3 0:15:00

And I need a query to give me an output with the sum of the sensors per day, something like this:

Day SENSOR1 SENSOR2 SENSOR3
06/12/2016 120 109 116
06/13/2016 155 162 123

    
asked by Marla 16.06.2016 в 05:45
source

3 answers

1

Extension Tablefunc

You can use the tablefunc extension that comes in the module contrib.
This extension has a function called crosstab that pivots the tables. That is, convert rows of type EAV into columns.

You have to create the extension first. This example is created in the public

schema
midb=# CREATE EXTENSION tablefunc WITH SCHEMA public;

Pivoted table

This query should do what you need. Remember to adjust the names of the tables, fields and data types to your particular case.

select * from public.crosstab (
'SELECT fecha, cod_sensor, sum(valor)
 FROM public.sensor_data
 GROUP BY fecha, cod_sensor ORDER BY fecha, cod_sensor'
) as ct(fecha date, "SENSOR1" numeric, "SENSOR2" numeric, "SENSOR3" numeric)

Grouping

You can do it too without installing anything. Directly with the grouping functions available by default.

The query would be:

select fecha, 
  max (case when cod_sensor = 'SENSOR1' then valor end) as "SENSOR1",
  max (case when cod_sensor = 'SENSOR2' then valor end) as "SENSOR2",
  max (case when cod_sensor = 'SENSOR3' then valor end) as "SENSOR3"
from 
(
  SELECT fecha, cod_sensor, sum(valor) valor
  FROM public.sensor_data 
  GROUP BY fecha, cod_sensor ORDER BY fecha, cod_sensor
) a
group by fecha
    
answered by 16.06.2016 / 19:56
source
0

Using group by and aggregations sum should be easy:

select [day], SUM(value) as Total, cod_sensor
from tableName
group by [day], cod_sensor

This what I would do would be to give you a result like this:

day Total sensor_code

06/12/2016 120 SENSOR1

06/12/2016 109 SENSOR2

06/12/2016 123 SENSOR3

06/13/2016 155 SENSOR1

06/13/2016 162 SENSOR2

06/13/2016 123 SENSOR3

How you want a single line to have all the sensors would need to do other operations. Confirm me if the current result is enough; otherwise I investigate more.

    
answered by 16.06.2016 в 11:17
0

Well, I think there are several ways to solve this query, I'll show you one of them:

SQL

    SELECT tbl.'day',
    (SELECT SUM(tbls1.'value') FROM 'tu_tabla' AS tbls1 WHERE tbls1.'cod_sensor' = 'SENSOR1' AND tbls1.'day' = tbl.'day') AS SENSOR1, 
    (SELECT SUM(tbls1.'value') FROM 'tu_tabla' AS tbls2 WHERE tbls2.'cod_sensor' = 'SENSOR2' AND tbls2.'day' = tbl.'day') AS SENSOR2,
    (SELECT SUM(tbls1.'value') FROM 'tu_tabla' AS tbls3 WHERE tbls3.'cod_sensor' = 'SENSOR3' AND tbls3.'day' = tbl.'day') AS SENSOR3,
    FROM 'tu_tabla' AS tbl 
    GROUP BY tbl.day

I explain:

Basically only 3 subqueries are created from the same table "tu_tabla" where we condition the sensor_code and add the total value.

I hope it will help you to clarify the problem.

    
answered by 16.06.2016 в 20:55