Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mysql "Where not in" using two columns

Tags:

mysql

I have one temporary table that contains userID and taskID. It is called CompletedTasks.
I have a second table that contains userID and taskID. It is called PlannedTasks.

I need to get a list of all taskIDs that were completed, but not planned.
So, I need to somehow weed out from completed tasks, all rows where both:

PlannedTasks.userID != CompletedTasks.userID  

AND

PlannedTasks.taskID != CompletedTasks.taskID 
like image 946
PFranchise Avatar asked Dec 08 '11 17:12

PFranchise


People also ask

How do I exclude a column in MySQL?

COLUMNS table holds all information about the columns in your MySQL tables. To exclude columns, you use the REPLACE() and GROUP_CONCAT() functions to generate the column names you wish to include in your SELECT statement later.

Can we use multiple columns in where clause?

But the WHERE.. IN clause allows only 1 column.

How do I query two columns in MySQL?

To select multiple columns from a table, simply separate the column names with commas! For example, this query selects two columns, name and birthdate , from the people table: SELECT name, birthdate FROM people; Sometimes, you may want to select all columns from a table.

Can we use two columns in where clause in SQL?

When we have to select multiple columns along with some condition, we put a WHERE clause and write our condition inside that clause. It is not mandatory to choose the WHERE clause there can be multiple options to put conditions depending on the query asked but most conditions are satisfied with the WHERE clause.


2 Answers

You can use this (more compact syntax):

SELECT * FROM CompletedTasks WHERE (userID, taskID) NOT IN       ( SELECT userID, taskID         FROM PlannedTasks       ) ; 

or the NOT EXISTS version (which although more complex, should be more efficient with proper indexes):

SELECT c.* FROM CompletedTasks AS c WHERE NOT EXISTS        ( SELECT 1         FROM PlannedTasks AS p         WHERE p.userID = c.userID           AND p.taskID = c.taskID       ) ; 

and of course the LEFT JOIN / IS NULL version that @jmacinnes has in his answer.

like image 79
ypercubeᵀᴹ Avatar answered Oct 02 '22 18:10

ypercubeᵀᴹ


Is this what you need?

select ct.* from completedTasks ct left outer join plannedTasks pt on ct.taskId = pt.TaskId and ct.userId = pt.userId where pt.taskId is null 

However, I agree with the comment - given what we know from the question a status column sounds like a better schema than two tables.

like image 25
jmacinnes Avatar answered Oct 02 '22 20:10

jmacinnes