Reputation: 79
I am working on implementation for a SQL which should display results with Union operation between Where and Having Clause. For example,
Select * from table where col1= 'get' group by col2 (OR/UNION) having avg(col3) >30 . This is not valid but trying to give use a case
The purpose of the sql statement is to return result set which satisfies both where and having conditions.
Lets say I have a table1, has with col1, col2, col3, col4 and large data in the table. Now, There is a use case in which user wants to see results when selects filters with specific crtieria col1 ='Y', avg(col2) >10, avg(col3*col4) =30 in filters list. Now, I have to create a criteria, such that, I should return all results which satisfies col1 ='Y' OR avg(col2) >10 OR avg(col3*col4) =30 , like we do in where clause with OR operator but here we have both where clause and having clause –
Like, the below query
resultset1 <= select * from table1 where col1= 'get'; resultset2 <= select * from table1 group by col2 having avg(col3) >30
final results = resultset1+ resultset2 Do any one have better approach or ideas in implementing such scenario?
Lets say I have filters combinations as below
col1 =23 OR avg(col2) >30 AND avg(col3) =10 OR avg(col1) <10 AND col2 =10
I need to display results satisfying these criteria in SQL
Upvotes: 0
Views: 1041
Reputation: 18408
SELECT <resultset1> --resultset based on a WHERE clause
UNION
SELECT <resultset2> --resultset based on HAVING
In general, if you want a union of resultsets, use ... UNION.
Using OR in a condition is equivalent to UNION (because the UNION operator is the relational algebra equivalent of logical disjunction), but it requires the scope of the involved conditions to be identical.
In this case, this is impossible because a HAVING condition applies not to the table mentioned in the SELECT, but instead to an intermediate table that is "silently" created by the GROUP clause. This is inevitably so because things like AVG,SUM,... only make sense if it is also determined which set of rows must be used to compute the AVG,SUM,... over, and that is what the GROUP BY specification does.
EDIT
In SQL, UNION comes in distinct flavours, UNION DISTINCT and UNION ALL. One eliminates duplicates, the other won't. If you want the exact same behaviour as OR, you'll obviously need the one that eliminates duplicates from its result set.
Upvotes: 0
Reputation: 24144
It's not clear what do you want from this quasi SQL. I guess you need to select records with two conditions col1= 'get'
AND /OR ? having avg(col3) >30
. So here is the solution:
Select * from table
where (col1= 'get')
OR
col2 in (SELECT col2 FROM table GROUP BY col2 HAVING avg(col3) >30)
If you need both conditions where true then replace OR with AND.
If you need to count AVG only for col1 = 'get'
then add this condition into the subquery:
Select * from table
where (col1= 'get')
OR
col2 in (SELECT col2 FROM table WHERE (col1= 'get')
GROUP BY col2
HAVING avg(col3) >30)
Upvotes: 0