我将内部联接更改为左联接

时间:2015-11-14 12:41:14

标签: mysql sql

我写sql

SELECT 
    count(*) as count,g.name
FROM
    test_scale g
        INNER JOIN
    test_user_scale_result a
        INNER JOIN
    en_org_user_department b
        INNER JOIN
    en_org_department d
        INNER JOIN
    test_scale_type e ON a.user_id = b.user_id
        AND g.id = a.scale_id
        AND b.department_id = d.id
        AND d.position LIKE CONCAT((SELECT 
                    position
                FROM
                    en_org_department
                WHERE
                    id = 8),
            '%')
        AND e.id = g.scale_type_id
        and b.status = 1
        and g.scale_type_id IN (1 , 9)
        and a.create_time BETWEEN '2015-01-07 18:09:45' and '2015-11-09 18:09:45'
        group by a.scale_id;

我运行正常。 但是当我从内到左改变时,就像

SELECT 
    count(*) as count,g.name
FROM
    test_scale g
        left JOIN
    test_user_scale_result a
        left JOIN
    en_org_user_department b
        left JOIN
    en_org_department d
        left JOIN
    test_scale_type e ON a.user_id = b.user_id
        AND g.id = a.scale_id
        AND b.department_id = d.id
        AND d.position LIKE CONCAT((SELECT 
                    position
                FROM
                    en_org_department
                WHERE
                    id = 8),
            '%')
        AND e.id = g.scale_type_id
        and b.status = 1
        and g.scale_type_id IN (1 , 9)
        and a.create_time BETWEEN '2015-01-07 18:09:45' and '2015-11-09 18:09:45'
        group by a.scale_id;
  

它错误20:37:15 SELECT * FROM test_user_scale_result a
  左JOIN en_org_user_department b离开JOIN
  en_org_department d左边JOIN test_scale_type e left   JOIN test_scale g ON a.user_id = b.user_id AND g.id =   a.scale_id AND b.department_id = d.id AND d.position   喜欢CONCAT((选择位置FROM   en_org_department WHERE id = 8),
  '%')和e.id = g.scale_type_id和b.status = 1
  和g.scale_type_id IN(1,9)和a.create_time BETWEEN   '2015-01-07 18:09:45'和'2015-11-09 18:09:45'错误代码:1064。你   您的SQL语法有错误;检查对应的手册   您的MySQL服务器版本,以便在''在线附近使用正确的语法   26 0.0060秒

2 个答案:

答案 0 :(得分:1)

我认为left join在加入后会立即需要on子句。真的,你应该总是这样做:

SELECT 
    count(*) as count,g.name
FROM
    test_scale g left JOIN
    test_user_scale_result a
    ON g.id = a.scale_id AND a.create_time BETWEEN '2015-01-07 18:09:45' and '2015-11-09 18:09:45' left JOIN
    en_org_user_department b
    ON a.user_id = b.user_id AND b.status = 1 left JOIN
    en_org_department d
    ON b.department_id = d.id AND
       d.position LIKE CONCAT((SELECT position FROM en_org_department WHERE id = 8),
                              '%') left JOIN
    test_scale_type e
    ON e.id = g.scale_type_id
WHERE g.scale_type_id IN (1 , 9)
group by a.scale_id;

注意:

  • 我非常确定特定表格的条件需要放在首先出现该表格的ON子句中。我不认为left join如果所有这些都填入最后的on条款中将会有效。
  • 第一个表的条件应该是where子句。否则,你会得到奇怪的结果。
  • 使用连接时,以下是一些简单的规则。 (1)除了ON之外,每个JOIN始终都有一个CROSS JOIN子句。 (2)永远不要在FROM条款中使用逗号(你不是这样做的,但我总是把它扔进去)。

答案 1 :(得分:0)

您应该将加入条件放在正确的ON子句中,而不是全部放在最终的ON中,如下所示:

SELECT      count(*) as count,
            g.name
FROM        test_scale g
LEFT JOIN   test_user_scale_result a
        ON  g.id = a.scale_id
        AND a.create_time BETWEEN '2015-01-07 18:09:45' and '2015-11-09 18:09:45'
LEFT JOIN   en_org_user_department b
        ON  a.user_id = b.user_id
        AND b.status = 1
LEFT JOIN   en_org_department d
        ON  b.department_id = d.id
        AND d.position LIKE CONCAT(
                (SELECT position
                FROM    en_org_department
                WHERE   id = 8),
                '%')
LEFT JOIN   test_scale_type e
        ON  e.id = g.scale_type_id
WHERE       g.scale_type_id IN (1, 9)
GROUP BY    g.name;

g.scale_type_id上的条件应出现在WHERE子句中,除非您确实要包含其他记录。

另请注意,建议按g.name分组,因为这是SELECT列的相关计数。在标准SQL中,您必须GROUP BY SELECT列表中的非聚合列。