Reputation: 41
I have two tables, one with a list of projects and who is assigned to each project, and one with names and information about contractors.
"Projects_table"
Project_ID Contractor_assigned Job_Complete
1 Jim Smith 1
2 John Smith 0
3 Edward Smith 0
4 Smith Smith 1
5 Candle Stick 1
and
"Contractors_Table"
Contractor_ID Name Drywall Insulation
1 Jim Smith 1 0
2 John Smith 0 1
3 Edward Smith 0 1
4 Smith Smith 0 1
5 Jack BeNimble 0 1
6 Jack BeQuick 1 0
7 Candle Stick 0 1
What I need, is to pull an SQL query that gives me a list of the Contractors of a certain type (Drywall or Insulator) who are currently not assigned to any job, so long as that job is also not marked "Complete."
I've tried a few versions of this, but with no success:
SELECT
Name FROM Contractors_Table
WHERE Contractors_Table.Insulation=1
AND Name NOT IN
(SELECT Contractor_assigned FROM Projects_table WHERE `Job_Complete` = 0)
What I'm hoping for output from my above example is to get back:
Jack BeNimble
Candle Stick
Those two Insulators are not currently assigned a job, excluding the "complete" job.
Upvotes: 0
Views: 58
Reputation: 15131
You should use NOT EXISTS
instead:
SELECT Name
FROM Contractors_Table c
WHERE c.Insulation = 1
AND NOT EXISTS
(SELECT 1
FROM Projects_table p
WHERE p.Job_Complete = 0
AND p.Contractor_assigned = c.Name)
You could refactor the query you are trying to do, but will take much more effort to use NOT IN
.
You should also use foreign keys
instead of names to compare data. You are duplicating information in relational database, which doesn't follow Normalization rules
Upvotes: 1
Reputation: 10226
Firstly your table design is wrong: you should store the Contractor_ID
in the project table, and not their names (what happens with homonyms???)
Secondly I don't understand why your query doesnt return the expected result because it looks correct. Maybe because you have a column named Name
, and this is a reserved keyword, and you should thus surround it with `
Anyway it's never efficient to do a NOT IN
You can rewrite that with an OUTER JOIN
:
SELECT C.`Name`
FROM Contractors_Table C
LEFT JOIN Projects_table P ON C.`Name` = P.`Contractor_assigned` AND P.`Job_Complete` = 0
WHERE C.Insulation=1
AND P.ID IS NULL --> This will ensure that you only get those who are not in the Project table
Upvotes: 1
Reputation: 127
Obviously a couple of queries (one for each type). If you use unique ID's in both tables for each of the contractors you can join the tables and select where Contractors_Table.drywall = 0 and Project_Table = 0 (Group by Contractor ID).
I think its just about getting your data sorted in your tables then writing the query.
HTH :-)
Upvotes: 0