Search code examples
sqlpostgresqloperator-precedence

logic in AND statements


I have this query that pulls data that I can use for some analysis:


SELECT   distinct egauge_analyze_2.dataid,     
date_trunc('hour', egauge_analyze_2.timestamp_localtime)::time AS HOUR, 
avg(egauge_analyze_2.use) AS USE   

FROM   dev.egauge_analyze_2

WHERE egauge_analyze_2.timestamp_localtime BETWEEN
       '2012-07-16 00:00:00' AND '2012-08-17 23:59:59' 

AND egauge_analyze_2.use IS NOT NULL

-- AND use > 0

GROUP BY 1,2 
ORDER BY 1,2

When I use it with the above (as-is) it gives me good data and throws out any dataids (and all their data) that have null values anytime, when I add the extra constraint of use > 0, it stops throwing out dataids will null values.

The data consist of dataids (a value for a unique device), a timestamp, and a USE (power draw of that device at that time) - I am trying to get seasonal profiles for the devices, but throw out whole devices that given null or erroneous (negative) data.

I would like it to throw out all dataids (and all their data) for any value of use that is null or <= 0. Ideas?


Solution

  • It is a little hard to follow what your question. I think you want to eliminate all dataids that have any use values that are NULL or negative. You can do this with a having clause:

    SELECT ea.dataid,     
           date_trunc('hour', ea.timestamp_localtime)::time AS HOUR, 
           avg(ea.use) AS USE   
    FROM dev.egauge_analyze_2 ea
    WHERE ea.timestamp_localtime BETWEEN '2012-07-16 00:00:00' AND '2012-08-17 23:59:59'
    GROUP BY 1,2
    having sum(case when use is null or use < 0 then 1 else 0 end) > 0
    ORDER BY 1,2
    

    In addition, I removed the distinct in the select clause, since it is unnecessary (you have a group by). I also gave the table a more readable alias, ea instead of the table name.