简体   繁体   中英

SQL LEFT JOIN ON A SINGLE TABLE

Assume table:

MyTable
idPrimary     idPerson     idSchool
-----------------------------------
1             20            6
2             20            3
3             21            2
4             22            6
5             23            6
6             24            3
7             22            7

I would like to find all the persons, who went to school 6 but did not go to school 2 or 3. That means that from the table above, the answer would be students 22 and 23. Student 20 went to school 6 but sadly went to school 3, thereby negating this student.

According to the matrix in question 38549 , I want the LEFT JOIN WHERE B.Key is NULL.

(Just out of curiosity is that what is called LEFT OUTER JOIN?)

The main formula is:

SELECT <SELECT_LIST> FROM TableA.A LEFT JOIN TableB.B ON A.Key = B.Key WHERE B.Key IS NULL;

Table A would be:

SELECT * FROM `MyTable` WHERE `idSchool` = '6';

Table B would be:

SELECT * FROM `MyTable` WHERE `idSchool` = '2' OR `idSchool` = '3';

The resultant table should be:

SELECT `idPerson` FROM SELECT * FROM `MyTable` WHERE `idSchool` = '6' LEFT JOIN SELECT * FROM `MyTable` WHERE `idSchool` = '2' OR `idSchool` = '3' ON `idSchool` = `idSchool` WHERE `idSchool` = NULL;

Sadly MySQL Workbench throws me an error:

Error Code: 1064. You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near

Near the LEFT JOIN, so basically the SQL engine does not like my TableA. If I wrap TableA in parenthesis, then I get an alias error.

What is the proper way to issue this query?

Do a LEFT JOIN, checking for the schools not wanted in the ON clause, and check for no match in the WHERE clause:-

SELECT DISTINCT a.idPrimary, a.idPerson, a.idSchool
FROM MyTable a
LEFT OUTER JOIN MyTable b
ON a.idPerson = b.idPerson
AND b.idSchool IN (2,3)
WHERE a.idSchool = 6
AND b.idSchool IS NULL

Use the AS keyword for your table aliases:

SELECT <SELECT_LIST>
  FROM TableA AS A
LEFT JOIN TableB AS B ON A.Key = B.Key
 WHERE B.Key IS NULL;

The syntax of a JOIN looks more like:

SELECT *
FROM someTable
LEFT JOIN ON someOtherTable ON (someTable.someColumn = someOtherTable.someOtherColumn)
WHERE
someTable.id = 1;

However in your case I think NOT EXISTS looks clearer:

SELECT t1.* 
FROM `MyTable` t1
WHERE t1.`idSchool` = '6'
AND NOT EXISTS (
        SELECT t2.idPerson 
        FROM MyTable t2 
        WHERE t2.idSchool IN (2,3) AND t2.idPerson = t1.idPerson);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM