Reputation: 4764
I am trying to get a MYSQL query right and it is not doing what I want.
Have table of people, table of tasks and table of people linked to tasks. This is for a page that lets users assign people to tasks. Tables have userid fields since different users are working with different groups of people and/or tasks. For each task, I want to populate a list of people the user can assign to the task that excludes any people already assigned.
Tables are as follows: people
id|person|userid
tasks
id|task|userid
taskperson
id|personid|taskid
The query I am working with is:
SELECT p.*,p.id as pid
FROM `people` p
LEFT JOIN `taskperson` tp
on p.id = tp.personid
WHERE p.person LIKE '%$str%' AND p.userid = '1'AND tp.personid NOT IN
(SELECT tp.personid FROM `taskperson` tp WHERE userid = '1' AND tp.taskid = '33' )
GROUP BY p.id
If you remove the NOT IN clause it will give you a list of people but does not exclude those already assigned.
If you include the NOT IN clause, when there are no rows in the table, taskperson for the user in question, ie no people have been assigned to the task, it does not show any people ie returns zero rows. It should show all people in that case.
Can anyone see out where I need to change this?
Thanks for any suggestions
Upvotes: 1
Views: 285
Reputation: 17
What I surmise according to your question...
CREATE TABLE PEOPLE(ID INTEGER,PERSON VARCHAR(20),USERID INTEGER); CREATE TABLE TASKS(ID INTEGER,TASK VARCHAR(20),USERID INTEGER); CREATE TABLE TASKPERSON(ID INTEGER,PERSONID INTEGER,TASKID INTEGER);
INSERT INTO PEOPLE VALUES(1,"RAHUL",1); INSERT INTO TASKS VALUES(1,NULL,1); INSERT INTO TASKPERSON VALUES(1,1,NULL);
INSERT INTO PEOPLE VALUES(1,"RAUNAK",1); INSERT INTO TASKS VALUES(1,"R",1); INSERT INTO TASKPERSON VALUES(1,1,33);
INSERT INTO PEOPLE VALUES(2,"PARTH",2); INSERT INTO TASKS VALUES(2,"P",2); INSERT INTO TASKPERSON VALUES(2,2,22);
INSERT INTO PEOPLE VALUES(3,"KANISHK",3); INSERT INTO TASKS VALUES(3,"K",3); INSERT INTO TASKPERSON VALUES(3,3,33);
INSERT INTO PEOPLE VALUES(4,"HEENA",4); INSERT INTO TASKS VALUES(4,NULL,4); INSERT INTO TASKPERSON VALUES(4,4,NULL);
When not including "NOT IN", you will retrieve the list of those people who are not allocated.
SELECT P.*,P.ID FROM PEOPLE P LEFT JOIN TASKPERSON TP ON P.ID=TP.PERSONID
WHERE P.USERID=1 AND TP.PERSONID IN(SELECT TP.PERSONID FROM TASKPERSON TP WHERE TP.PERSONID=1 AND TP.TASKID=33)
GROUP BY P.ID
Upvotes: 0
Reputation: 33935
I'm not sure, but perhaps this is what you're after...
SELECT DISTINCT p.*
FROM people p
LEFT
JOIN taskperson tp
ON tp.personid = p.id
AND taskid = 33
WHERE p.person LIKE '%$str%'
AND p.userid = 1
AND tp.personid IS NULL;
Upvotes: 0
Reputation: 24134
I think the issue here is in the condition AND tp.personid NOT IN (....)
if tp.personid is NULL then this condition is ALWAYS FALSE. So you don't need LEFT JOIN at all.
SELECT p.*,p.id as pid
FROM `people` p
WHERE p.person LIKE '%$str%' AND p.userid = '1'AND p.id NOT IN
(SELECT tp.personid FROM `taskperson` tp WHERE userid = '1' AND tp.taskid = '33' )
Upvotes: 0
Reputation: 4098
I think you need IS NULL
.
SELECT p.*,p.id as pid
FROM `people` p
LEFT JOIN `taskperson` tp
on p.id = tp.personid
WHERE p.person LIKE '%$str%' AND p.userid = '1' AND tp.personid IS NULL
GROUP BY p.id
Judging from your removal of the NOT IN clause, this will exclude people that have already been assigned. WHERE tp.personid IS NULL
will show only those people that do not have a match from the LEFT JOIN
.
Upvotes: 1