【问题标题】:right outer join between 2 tables两个表之间的右外连接
【发布时间】:2014-04-15 22:07:57
【问题描述】:

我有两张表,一张叫Classes,其中包含ClassName,一张叫FullSchedule,其中包含ClassNameDayValTimeVal等信息。

我想要做的是,我想选择在特定日期和时间没有使用的类,这是我的查询:

    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。没有错 - 这对许多人(包括我)来说只是有点违反直觉 - 但也许这是西方的,从左到右的写作方式。

标签: php mysql sql 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 表中有同名的类吗?
  • SELECT Classes.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 行以及DayValTimeVal 值分别等于$day$time 的行.

WHERE 子句消除了FullSchedule 表(具有ClassNameDayValTimeVal 限制)没有匹配记录的行。

【讨论】:

    【解决方案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;
    

    考虑将日期和时间存储为单个实体。好得多的主意。

    【讨论】:

      猜你喜欢
      • 2013-08-06
      • 1970-01-01
      • 2017-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多