Reputation: 9101
My requirement is to show one record when there are no values in the table. I have achieved with following query:
SELECT TRUNC (SYSDATE - 1) DATE1,
NVL(AVG (column1),0) col1,
NVL(AVG (column2),0) col2,
COUNT ( * ) TOTAL
FROM table1
WHERE column3 = 0 AND TRUNC (UTC_TIMESTAMP + TZ_OFFSET / 24) = TRUNC (SYSDATE - 1) ;
now my problem here is when I add groupby
clause to above query result is 0
records are returned.
changed query
My requirement is to show one record when there are no values in the table. I have achieved with following query:
SELECT TRUNC (SYSDATE - 1) DATE1,
NVL(AVG (column1),0) col1,
NVL(AVG (column2),0) col2,
COUNT ( * ) TOTAL
FROM table1
WHERE column3 = 0 AND TRUNC (UTC_TIMESTAMP + TZ_OFFSET / 24) = TRUNC (SYSDATE - 1)
GROUP BY TRUNC (SYSDATE - 1) ;
now I am confused about this behaviour. Why am I getting this strange behaviour?
25-05-2014 0 0 0
Upvotes: 0
Views: 64
Reputation: 1269583
The explanation is a bit arcane, because aggregation queries have an inconsistency when used with and without a group by
clause. Your first query is an aggregation query:
SELECT TRUNC(SYSDATE - 1) as DATE1, NVL(AVG (column1),0) as col1, NVL(AVG (column2),0) as col2,
COUNT ( * ) TOTAL
FROM table1
WHERE column3 = 0 AND TRUNC(UTC_TIMESTAMP + TZ_OFFSET / 24) = TRUNC(SYSDATE - 1) ;
This query treats all the matching rows (even none) as a single group. It will always return one row, even when no rows match. This is when COUNT(*)
can return 0
. By the way, you are allowed to include TRUNC(SYSDATE - 1)
because it is a "constant" (relative to the query).
When you add the group by
, the semantics change. So this query:
SELECT TRUNC(SYSDATE - 1) as DATE1, NVL(AVG (column1),0) as col1, NVL(AVG (column2),0) as col2,
COUNT ( * ) TOTAL
FROM table1
WHERE column3 = 0 AND TRUNC(UTC_TIMESTAMP + TZ_OFFSET / 24) = TRUNC(SYSDATE - 1)
GROUP BY TRUNC(SYSDATE - 1) ;
This query returns each group represented by the group by
. If there are no groups, then no rows are returned. In this case, all rows are filtered out by the where
clause, so no rows are returned.
Upvotes: 1
Reputation:
select TRUNC (SYSDATE - 1) d,
col1,
col2,
total
from (
SELECT NVL(AVG (column1),0) col1,
NVL(AVG (column2),0) col2,
COUNT (* ) TOTAL
FROM table1
WHERE column3 = 0 AND TRUNC (UTC_TIMESTAMP + TZ_OFFSET / 24) = TRUNC (SYSDATE - 1))
group by TRUNC (SYSDATE - 1),
col1,
col2,
total
Edit---------- added group by to outer query
Upvotes: 0