【问题标题】:MySQL Inner Join On Clause Field Not Found未找到子句字段上的 MySQL 内部联接
【发布时间】:2014-05-06 12:32:37
【问题描述】:

我当前的表格如下所示:

Lessons:
+-----------------------------------+
| ID | Name  | StartDate  | Repeats |
|----|-------|------------|---------|
| 1  | Maths | 2014-05-05 |    5    |
| 2  | Lunch | 2014-05-05 |    1    |
| 3  | Comp  | 2014-05-05 |    7    |
+-----------------------------------+

LessonTimes:
+-------------------------------------+
| ID | LessonID | StartTime | EndTime |
|----|----------|-----------|---------|
| 1  |    1     | 10:00:00  |    5    |
| 2  |    2     | 12:25:00  |    1    |
| 3  |    3     | 14:00:00  |    7    |
+-------------------------------------+

Tally:
+----+
| ID |
|----|
| 1  |
| 2  |
| .  |
| .  |
+----+

我有在特定开始日期的特定天数内重复的事件。我目前的查询是:

SELECT E.ID
     , E.Name
     , E.StartDate
     , E.Repeats
     , A.ShowDate
     , DATEDIFF(E.StartDate, A.ShowDate) diff
     , T.StartTime
     , DATE_ADD(A.ShowDate, INTERVAL T.StartTime HOUR_SECOND) ShowTime 
  FROM Planner_Lessons E
     , ( SELECT DATE_ADD('2014-05-05 00:00:00',INTERVAL ID DAY ) ShowDate
           FROM `Planner_Tally`
          WHERE (DATE_ADD('2014-05-05 00:00:00',INTERVAL ID DAY )<= '2014-05-30 00:00:00')
          ORDER 
             BY Id ASC 
       ) A 
    LEFT 
    JOIN Planner_LessonTimes T 
      ON T.LessonID = E.ID 
   WHERE MOD(DATEDIFF(E.StartDate, A.ShowDate), E.Repeats) = 0 
     AND A.ShowDate >= E.StartDate

但我得到的错误是在“ON”子句中找不到字段E.ID

我发现查询的原始问题在这里 - PHP/MySQL: Model repeating events in a database but query for date ranges

【问题讨论】:

  • 我认为你离开了 A 表,所以你不能设置条件 T.LessonID=E.ID
  • Planner_lessons 和 A 没有 on 子句或内/外连接语法
  • 不要混合隐式(逗号)和显式连接语法。事实上,根本不要使用隐式连接语法。另外,我怀疑将 'id' 与 DATEDIFF('2014-05-30 00:00:00','2014-05-05 00:00:00') 的结果进行比较会更有效

标签: mysql sql datetime inner-join repeat


【解决方案1】:

这是您的查询,格式化以便人们可以阅读:

SELECT E.ID, E.Name, E.StartDate, E.Repeats, A.ShowDate, DATEDIFF(E.StartDate, A.ShowDate) AS diff,
       T.StartTime, DATE_ADD(A.ShowDate, INTERVAL T.StartTime HOUR_SECOND) AS ShowTime
FROM Planner_Lessons AS E,
     (SELECT DATE_ADD('2014-05-05 00:00:00',INTERVAL ID DAY) as ShowDate
      FROM `Planner_Tally`
      WHERE (DATE_ADD('2014-05-05 00:00:00',INTERVAL ID DAY)<='2014-05-30 00:00:00')
      ORDER BY Id ASC
     ) A LEFT JOIN
     Planner_LessonTimes AS T
     ON T.LessonID=E.ID
WHERE MOD(DATEDIFF(E.StartDate, A.ShowDate), E.Repeats)=0 AND A.ShowDate>=E.StartDate;

您缺少隐式和显式 join 语法。由于 MySQL 范围规则,E 中的列在逗号后无法识别。

SELECT E.ID, E.Name, E.StartDate, E.Repeats, A.ShowDate, DATEDIFF(E.StartDate, A.ShowDate) AS diff,
       T.StartTime, DATE_ADD(A.ShowDate, INTERVAL T.StartTime HOUR_SECOND) AS ShowTime
FROM Planner_Lessons E JOIN
     Planner_LessonTimes T
     ON T.LessonID = E.ID JOIN
     (SELECT DATE_ADD('2014-05-05 00:00:00',INTERVAL ID DAY) as ShowDate
      FROM `Planner_Tally`
      WHERE (DATE_ADD('2014-05-05 00:00:00',INTERVAL ID DAY)<='2014-05-30 00:00:00')
      ORDER BY Id ASC
     ) A 
     ON MOD(DATEDIFF(E.StartDate, A.ShowDate), E.Repeats)=0 AND A.ShowDate>=E.StartDate;

我将left join 切换为内部联接,因为where 子句撤消了外部联接。

【讨论】:

    【解决方案2】:

    您错过了别名为 A 的子查询的 JOIN 条件。假设 Planner_Tally 表包含列 ID ,您可以添加连接条件 ON A.ID=E.ID 如下所示

    SELECT E.ID, E.Name, E.StartDate, E.Repeats, A.ShowDate, 
           DATEDIFF(E.StartDate, A.ShowDate) AS diff, T.StartTime,
           DATE_ADD(A.ShowDate, INTERVAL T.StartTime HOUR_SECOND) AS ShowTime 
    FROM Planner_Lessons AS E
    LEFT JOIN Planner_LessonTimes AS T ON T.LessonID=E.ID 
    LEFT JOIN (
               SELECT DATE_ADD('2014-05-05 00:00:00',INTERVAL ID DAY) as ShowDate,ID
               FROM `Planner_Tally`
               WHERE (DATE_ADD('2014-05-05 00:00:00',INTERVAL ID DAY)<='2014-05-30 00:00:00')
     ) A  ON A.ID=E.ID 
    WHERE MOD(DATEDIFF(E.StartDate, A.ShowDate), E.Repeats)=0 
          AND A.ShowDate>=E.StartDate
    ORDER BY E.Id ASC
    

    【讨论】:

      【解决方案3】:

      顺便说一句,考虑以下...(ints 是一个从 0 到 9 的整数表)

      EXPLAIN
      SELECT * FROM ints WHERE '2014-05-05 00:00:00' + INTERVAL i DAY < '2014-30-30 00:00:00'\G
      *************************** 1. row ***************************
                 id: 1
        select_type: SIMPLE
              table: ints
               type: index
      possible_keys: NULL
                key: PRIMARY
            key_len: 4
                ref: NULL
               rows: 10
              Extra: Using where; Using index
      1 row in set (0.00 sec)
      
      EXPLAIN
      SELECT * FROM ints WHERE i < DATEDIFF('2014-05-30 00:00:00','2014-05-05 00:00:00')\G
      *************************** 1. row ***************************
                 id: 1
        select_type: SIMPLE
              table: ints
               type: index
      possible_keys: PRIMARY
                key: PRIMARY
            key_len: 4
                ref: NULL
               rows: 10
              Extra: Using where; Using index
      1 row in set (0.00 sec)
      

      如您所见,尽管两个查询在逻辑上相同,但第一个为possible_keys 注册了NULL。

      我们现在已经达到了我对索引的全部了解。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-10
        • 2011-12-02
        • 1970-01-01
        • 2014-11-21
        • 1970-01-01
        相关资源
        最近更新 更多