Reputation: 137
SQL noobie here, tried my luck googling around, but came up empty or didn't know the proper keyword. Still, feeling quite awkward between all those advanced questions, however still hopeful to get a solution and learn.
Let's suppose we have a table representing participants for different teams for a children sports tournament.
Participant table:
Our goal is to select out participants that have chosen a WRONG team. Let's suppose that the conditions for the teams are as such:
team Yellow = boys with age 12;
team Red = girls with age 13;
team Blue = boys with age 11;
That would mean that the incorrect registrants are Sarah (incorrect gender, correct age), Jack (incorrect gender and age) and Mary who all should therefore be included in the result of the query.
However I'm struggling with creating a SQL query that would consider conditions from multiple fields (comparing team towards gender and age at the same time) + having more than one set of comparison done at the same time (looking for incorrect participants from 3 teams at the same time).
Help is much appreciated!
Upvotes: 1
Views: 145
Reputation: 14842
There are a few things you haven't mentioned about your team restrictions:
Since that's not stated, I'm going to provide a generic solution that makes it easy to extend the valid teams. And the query will return all participants that don't match at least one valid team. (NOTE: It may be that there is no valid team for a particular participant.)
Approach:
The CTE for ValidTeams
below could easy be replaced with a table if your RDBMS doesn't support CTE's. NOTE: If there are many permutations of valid gender/age/team a separate table will be better.
;WITH ValidTeams AS (
SELECT 'Yellow' AS Team, 'M' AS Gender, 12 AS Age
UNION ALL SELECT 'Red', 'F', 13
UNION ALL SELECT 'Blue', 'M', 11
)
SELECT Name, Gender, Age, Team AS InvalidTeam
FROM Participants p
WHERE NOT EXISTS (
SELECT *
FROM ValidTeams v
WHERE v.Gender = p.Gender
AND v.Age = p.Age
AND v.Team = p.Team
)
Upvotes: 0
Reputation:
You didn't state your DBMS so this is ANSI SQL:
Just select all rows that do not comply with any of the rules:
select *
from participants
where (team, gender, age) not in ( ('Yellow', 'M', 12),
('Red', 'F', 13),
('Blue', 'M', 11) );
Online example: http://rextester.com/ZTEON26060
Upvotes: 4
Reputation: 49270
You can use a combination of or
and and
to do this.
select * from yourtable
where (team ='Yellow' and not (gender = 'M' and age = 12))
or (team ='Red' and not (gender = 'F' and age = 13))
or (team ='Blue' and not (gender = 'M' and age = 11))
Upvotes: 0
Reputation: 117530
Main thing here is you have to convert your team rules into some kind of proper data structure. You can put it into the table, or use derived table, like this:
select *
from participants as p
where
not exists (
select *
from (values
('Yellow', 'M', 12),
('Red', 'F', 13),
('Blue', 'M', 11)
) as t(Team, Gender, Age)
where
t.Team = p.Team and
t.Gender = p.Gender and
t.Age = p.Age
)
Or you can check for correct team and then compare with current team:
select
p.*, t.Team as Correct_Team
from participants as p
left join (values
('Yellow', 'M', 12),
('Red', 'F', 13),
('Blue', 'M', 11)
) as t(Team, Gender, Age) on
t.Gender = p.Gender and
t.Age = p.Age
Upvotes: 1
Reputation: 780
You can try this :
Select
Name,
Gender,
Age,
Team AS Chosen_team,
Case when Gender='M' and Age=12 Then 'Yellow'
when Gender='F' and Age=13 then 'Red'
when gender='M' and Age=11 then 'Blue'
End as Ideal_team,
Case when Chosen_team <> Ideal_team then 'FALSE' ELSE 'TRUE'
from your_table;
Now select the records with value false. You will get your list.
Upvotes: 0