左连接的{MySql多表查询

时间:2017-02-01 03:20:33

标签: mysql join left-join

我问这个,因为我找不到使用左连接查询多个表的确切示例,我对使用连接有点新意。我在这里要做的是加入表user_listleave_record,以便从user_list表上的两个表格中获取数据。因为没有这样做,一些没有休假记录的用户将不会被显示。

现在,当我运行以下代码时,它会显示Unknown column 'a.id' in 'on clause'。但是这个专栏确实存在于我的表格中。如果有人可以指出我的错误,我很感激。先感谢您。 : - )

SELECT a.id,
       CONCAT(a.firstname, a.lastname) AS "name",
       a.date_joined,a.job_status,
       d.description,
       d.annual_cf AS 'allowed_cf',
       f.2016 AS "lastyear",
       g.2016 AS "last_annual_cf",
       h.2016 AS "ot_convert",
       f.2017 AS "current_ent",
       g.2017 AS "current_annual_cf",
       h.2017 AS "current_ot_convert",
      SUM(CASE WHEN b.start_date BETWEEN c.entitlement_start_date AND
                    c.entitlement_extention_date AND
                    b.submit_date BETWEEN c.entitlement_start_date AND
                    c.system_freez_start_date AND b.leave_type = '1' AND
                    b.s_status = 'Approved' AND b.status <> 'Canceled'
               THEN b.no_days ELSE 0 END) a_annual
FROM user_list a,
     leave_records b,
     system_settings c,
     job_category d, 
     annual_leave_ent f,
     annual_cf g,
     ot_convert h
LEFT JOIN (SELECT id FROM leave_records) AS ba
    ON a.id = ba.id
WHERE f.id = a.id AND a.enabled <> 'no' AND g.id = a.id AND h.id = a.id AND
      d.id = a.job_category AND a.company='14' AND
      c.year_id='2016'
GROUP BY a.id
ORDER BY a.id

1 个答案:

答案 0 :(得分:2)

不要将连接操作的旧学校逗号语法与较新的JOIN关键字混合使用。并将连接谓词移动到适当的ON子句而不是WHERE子句。

(它已经超过了抛弃逗号语法的时间; JOIN关键字足够长,以至于很难将其称为“更新”。对于任何新查询,请丢弃逗号。(是的,逗号语法仍然有效,但这是为了兼容性,所以古老的SQL仍然会运行。)

我不明白为什么你需要交叉连接和leave_records表的外连接。但目前尚不清楚你想要实现的目标。

我们不知道引用的表中id是否是UNIQUE。如果不了解这一点,看起来有可能生产半笛卡尔积。

没有样本数据,也没有预期的结果可供比较,我们只是在猜测。

但就LEFT OUTER JOIN的查询语法而言,我认为查询看起来像这样。 (请注意,leave_records的第一个引用已被删除。)

SELECT a.id
     , CONCAT(a.firstname,a.lastname) AS `name`
     , a.date_joined
     , a.job_status
     , d.description
     , d.annual_cf  AS `allowed_cf`
     , f.2016       AS `lastyear`
     , g.2016       AS `last_annual_cf`
     , h.2016       AS `ot_convert`
     , f.2017       AS `current_ent`
     , g.2017       AS `current_annual_cf`
     , h.2017       AS `current_ot_convert`
     , SUM( CASE
            WHEN b.start_date BETWEEN c.entitlement_start_date
                                  AND c.entitlement_extention_date
            AND b.submit_date BETWEEN c.entitlement_start_date
                                  AND c.system_freez_start_date
            AND b.leave_type        = '1'
            AND b.s_status          = 'Approved'
            AND b.status           <> 'Canceled'
           THEN b.no_days
           ELSE 0
           END
       ) AS a_annual
  FROM user_list a
  JOIN system_settings c
    ON c.year_id = '2016'
  JOIN job_category d
    ON d.id = a.job_category
  JOIN annual_leave_ent f
    ON f.id = a.id 
  JOIN annual_cf g
    ON g.id = a.id
  JOIN ot_convert h
    ON h.id = a.id
  LEFT
  JOIN leave_record b
    ON b.id = a.id
 WHERE a.enabled <> 'no'
   AND a.company = '14'
 GROUP BY a.id
 ORDER BY a.id

我会测试查询,不用 GROUP BY而不 SUM()聚合,以验证查询是否返回行我们期待。在我确定之后,我会添加GROUP BYSUM()聚合以获得合并结果。