两个表之间的右外连接
Posted
技术标签:
【中文标题】两个表之间的右外连接【英文标题】:right outer join between 2 tables 【发布时间】:2014-04-15 22:07:57 【问题描述】:我有两张表,一张叫Classes
,其中包含ClassName
,一张叫FullSchedule
,其中包含ClassName
、DayVal
和TimeVal
等信息。
我想要做的是,我想选择在特定日期和时间没有使用的类,这是我的查询:
SELECT `Classes`.`ClassName`
FROM `FullSchedule`
RIGHT OUTER JOIN `Classes`
ON `FullSchedule`.`ClassName` = `Classes`.`ClassName`
WHERE `FullSchedule`.`DayVal` = '$day' AND `FullSchedule`.`TimeVal` = `$time`
虽然我使用RIGHT OUTER JOIN
,但结果是使用的类(常见的),即使我将其更改为:
ON `FullSchedule`.`ClassName` != `Classes`.`ClassName`
它向我显示所有类,无论我如何更改它,它要么获取所有类,要么只获取正在使用的类。如何获取未使用的课程?
【问题讨论】:
请注意,实际上没有人使用 RIGHT JOIN。没有错 - 这对许多人(包括我)来说只是有点违反直觉 - 但也许这是西方的,从左到右的写作方式。 【参考方案1】:试试这个:
SELECT `Classes`.`ClassName`
FROM `Classes`
WHERE Classes`.`ClassName` not in (
SELECT `FullSchedule`.`ClassName`
FROM `FullSchedule`
WHERE `FullSchedule`.`DayVal` = '$day' AND `FullSchedule`.`TimeVal` = `$time` )
【讨论】:
我都试过了,但还是不行,它给了我所有的课程:/ 您确定在 FullSchedule 和 Classes 表中有同名的类吗? SELECTClasses
.ClassName
FROM Classes
WHERE Classes.
ClassName` not in ( SELECT FullSchedule
.ClassName
FROM FullSchedule
)所有课程?
它返回零行!
那么变量 $day 和 $time 的问题。查询没问题。【参考方案2】:
首先从表FullSchedule
中检索具有WHERE
条件的数据,然后RIGHT JOIN
它到Classes
:
SELECT
c.`ClassName`
FROM (
SELECT
`ClassName`
FROM
`FullSchedule`
WHERE
`DayVal` = '$day' AND `TimeVal` = '$time'
) f RIGHT OUTER JOIN `Classes` c
ON f.`ClassName` != c.`ClassName`
【讨论】:
@Ibraheem Ismail :echo
您的查询,复制输出并在您的 sql 管理工具(如 phpmyadmin)中执行它。如果它返回零行,那么问题出在您的数据库中,否则,如果它返回错误,您将绝对确定建议的查询不正确。【参考方案3】:
JOIN 选项的替代方案:
SELECT c.ClassName
FROM Classes c
WHERE NOT EXISTS ( SELECT *
FROM FullSchedule fs
WHERE fs.DayVal = $day
AND fs.TimeVal = $time
AND fs.ClassName = c.ClassName )
我建议您将所有三种解决方案都放入您的分析器中,并比较执行计划以找出最适合您的环境的方案。
如果RIGHT OUTER JOIN
语法是绝对必要的:
SELECT c.ClassName
FROM FullSchedule fs
RIGHT OUTER JOIN Classes c
ON fs.ClassName = c.ClassName
AND fs.DayVal = $day
AND fs.TimeVal = $time
WHERE fs.ClassName IS NULL
RIGHT OUTER JOIN
确保Classes
表返回其所有行,然后匹配ClassName
上的FullSchedule
行以及DayVal
和TimeVal
值分别等于$day
和$time
的行.
WHERE
子句消除了FullSchedule
表(具有ClassName
、DayVal
和TimeVal
限制)没有匹配记录的行。
【讨论】:
【参考方案4】: SELECT c.ClassName
FROM classes c
LEFT
JOIN FullSchedule s
ON s.ClassName = c.ClassName
AND s.DayVal = '$day'
AND s.TimeVal = '$time' -- <-- NOT BACKTICKS
WHERE s.ClassName IS NULL;
考虑将日期和时间存储为单个实体。好得多的主意。
【讨论】:
以上是关于两个表之间的右外连接的主要内容,如果未能解决你的问题,请参考以下文章