I am a sql newbie.
I have data in a mysql db that looks like
col1. | col2. | col3. | col4. | col5. |
---|---|---|---|---|
a | b | true | true | c |
a | d | false | false | e |
a | b | false | false | c |
a | f | false | false | g |
a | b | false | false | c |
i | b | false | false | j |
a | d | true | true | e |
I would like to write a query that
a) finds all rows that have col3 and col4 both set to true (so the first and last rows of the table above)
b) finds all rows that have the same col1 and col2 as the rows in a) (so the 3rd and 5th row have the same col1 and col2 as the first row, and the 2nd row has the same col1 and col2 as the last row)
c) Removes the rows in a) and b) returning all other rows
So the result returned by the query would be
col1. | col2. | col3. | col4. | col5. |
---|---|---|---|---|
a | f | false | false | g |
i | b | false | false | j |
For a) I could create a sub-table like
select col1, col2, col3, col4, col5 from the_table as a_table where col3=’true’ and col4=’true’
For b) I probably would have to do a lookup into a)
Then c) would subtract the result of b) from the full table
Is there a quicker way with group by?
3
Answers
You can use a subquery to identify the col3 & col4 = true conditions, then by using a left join to that subquery joining via cols 1 & 2 you find all the matching rows. Then finally, filter for only the unmatched rows via an IS NULL condition:
You can simply use
NOT EXISTS
as follows:Yes, aggregation can help here. You want to find at col1/col2 groups for which not exists a col3=true/col4=true row.
gives you a 1 for a col1/col2 group that has a col3=true/col4=true row, and 0 for the other groups, because in MySQL true=1, false=0. Thus
MAX(<bool expression>)
gives you a 1, if at least one row matches the condition and false otherwise.This must be done in a subquery, because window functions (
MAX OVER
here) are executed last in a query. There exist DBMS that have aQUALIFY
clause for this that comes after window functions in execution order, but MySQL doesn’t feature this clause.