I am writing for a sub-scenario of the question. I am posting one solution that works for ALL of You THAT HAVE GROUPED QUERY and who wandered like me how to implement the logic to have a row with default values if the query with WHERE CLAUSE returns NO ROWS in CASE 1 and in CASE 2 I will show you some approach of filtering more than ONE ROW.
Hope it will help.
CASE 1
One approach is to use UNION
operator between set of default values and set from filtered rows you want.
You can do this:
- Create SELECT Statement with your default values.
- Then UNION the SELECT Statement from 1. with your desired QUERY (add some WHERE clause, GROUP BY, whatever you want). For demonstration purposes, we will query the id column.
- Add column row_number where the default set
row_number = 0
and the queried set row_number = 1
.
- Order by the row_number column in DESC order (in order to have always in first place the filtered rows:
order by row_number desc
- Then QUERY the whole statement and LIMIT the result by 1.
- this will return the filtered row (if any) or the default row.
RESULT with FILTERED ROWS
| id | avg_column_val | row_number |
------------------------------------------------
| 80 | 1 | 1 |
| 0 | 0 | 0 |
WHEN you LIMIT 1 you will get the filtered rows
or
RESULT with DEFAULT ROWS
| id | avg_column_val | row_number |
----------------------------------------------
| 0 | 0 | 0 |
WHEN you LIMIT 1 you will get the default rows
FINAL QUERY
select * from (
select 0 as id, 0 as avg_column_val, 0 as row_number
union
select t.id, avg(some_column) as avg_column_val, 1 as row_number
from t_table as t
where t.id = @p_id
group by t.id
order by row_number desc
) as temp
limit 1;
CASE 2
Of course, if you want more rows to be returned from WHERE CLAUSE, you can execute your query and COUNT(*)
the result to check if there are ANY rows.
Then you can limit by the counted rows and it will return them: (+1 is in case where @p_counted_rows = 0 and you want to return the default values)
Note that you SHOULD set SQL_SELECT_LIMIT to your counted query (Set SQL_SELECT_LIMIT = @p_counted_rows + 1;
)-> This will LIMIT the exact number of rows WITHOUT writing LIMIT CLAUSE. When you finish your query - SET SQL_SELECT_LIMIT to DEFAULT (Set SQL_SELECT_LIMIT = Default;
)
- This needs to be done because **LIMIT clause cannot use variable**.
FINAL QUERY
set @p_counted_rows = 0;
select @p_counted_rows = count(*)
from
t_table as t
where t.id = @p_id;
Set SQL_SELECT_LIMIT = @p_counted_rows + 1;
select * from (
select 0 as id, 0 as avg_column_val, 0 as row_number
union
select t.id, avg(some_column) as avg_column_val, 1 as row_number
from t_table as t
where t.id = @p_id
order by row_number desc
) as temp;
Set SQL_SELECT_LIMIT = Default;
Hope this helps everyone.
Cheers, Happy coding!