MariaDB 10.1左外连接的行为类似于内连接 - 由GROUP BY引起

时间:2017-11-21 11:26:02

标签: mysql left-join inner-join mariadb

我已经从MySQL 5.6更新到MariaDB 10.1,我在获取我的" LEFT JOIN"时遇到了一些问题。工作。

SELECT * FROM users LEFT JOIN HOURS ON users.id = hours.user;

按预期返回19行

SELECT  *
    FROM  users
    LEFT JOIN (
        SELECT  *
            FROM  HOURS
            WHERE  stop IS NULL
              ) as hours2
        ON users.id = hours2.user;

返回24行?!?

SELECT  `users`.`initials` AS 'Initials', `users`.`name` AS 'Bruger' ,
        `projects`.`id` AS 'ProjectId', `projects`.`name` AS 'Project',
        `work_type`.`name` AS 'Arbejde'
    FROM  `users`
    LEFT JOIN  (
        SELECT  `hours`.`user`, `hours`.`work_type`, `hours`.`project`
            FROM  `hours`
            WHERE  `id` IN (
                SELECT  max(`id`) AS `id`
                    FROM  `hours`
                    WHERE  `stop` IS NULL
                    GROUP BY  `user`)
               ) AS `hours`  ON `hours`.`user` = `users`.`id`
    LEFT JOIN  `projects`   ON `projects`.`id` = `hours`.`project`
    LEFT JOIN  `work_type`  ON `work_type`.`id` = `hours`.`work_type`
    WHERE  `users`.`status` = 1
    ORDER BY  `users`.`name`;

返回0行(以小时为单位的所有行都有一个停止值atm)

我希望在所有3个查询中获得19行,我可能做错了,但无法谷歌解决方案。

在MySQL 5.6上使用的查询

Type   Vector
A      [0.2340, 0.5463, 0.5652, 0.3243, 0.3243]
B      [0.3244, 0.5566, 0.2344, 0.1213, 0.9821]
C      [0,5652,  0.3453, 0.3454, 0.5656, 0.6766]
D      [0,5125,  0.3345, 0.1112, 0.4545, 0.6324]

在更新之前总是返回17行(用户中有19行,其中17行具有status = 1)

但是现在这个查询只返回有"停止" = null。

3 个答案:

答案 0 :(得分:0)

您的overridden表肯定有一些重复值为hours的行。任何一种联接都会生成结果集行,这些行包含符合user条件的两个连接表的所有可能组合。

答案 1 :(得分:0)

据我所知,在不知道数据模型的情况下,此查询在5.6(在sqlfiddle中测试)和mariadb中的工作方式完全相同。 给出这样的模型

Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 11
Server version: 10.1.14-MariaDB mariadb.org binary distribution

Copyright (c) 2000, 2016, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [sandbox]> select id,username,status from users where id < 4;
+----+----------+--------+
| id | username | status |
+----+----------+--------+
|  1 | John     |      1 |
|  2 | Jane     |      1 |
|  3 | Ali      |      1 |
+----+----------+--------+
3 rows in set (0.00 sec)

drop table if exists hours,projects,work_type;
create table hours(id int auto_increment primary key,`user` int,work_type int, project int, `stop` varchar(3) );

create table projects(id int, name varchar(5));

create table work_type (id int, name varchar(3));

truncate table hours;

insert into hours  (`user`,work_type,project,`stop`) values (1,1,1,'atm'),(1,1,1,null),(2,null,1,null);
insert into projects values (1,'abc');
insert into work_type values (1,'aaa'),(2,'bbb');

查询

MariaDB [sandbox]> SELECT `users`.`username` AS 'Bruger' , `projects`.`id` AS 'ProjectId', `projects`.`name` AS 'Project', `work_type`.`name` AS 'Arbejde'
    -> FROM `users`
    -> LEFT JOIN (SELECT `hours`.`user`, `hours`.`work_type`, `hours`.`project`
    -> FROM `hours`
    -> WHERE `id`
    ->            IN (SELECT max(`id`) AS `id`
    ->   FROM `hours`
    -> WHERE `stop` IS NULL
    -> GROUP BY `user`
    -> )
    ->   ) AS `hours` ON `hours`.`user` = `users`.`id`
    -> LEFT JOIN `projects` ON `projects`.`id` = `hours`.`project`
    -> LEFT JOIN `work_type` ON `work_type`.`id` = `hours`.`work_type`
    -> WHERE `users`.`status` = 1 and users.id < 4
    -> ORDER BY `users`.`username`;
+--------+-----------+---------+---------+
| Bruger | ProjectId | Project | Arbejde |
+--------+-----------+---------+---------+
| Ali    |      NULL | NULL    | NULL    |
| Jane   |         1 | abc     | NULL    |
| John   |         1 | abc     | aaa     |
+--------+-----------+---------+---------+
3 rows in set (0.00 sec)

答案 2 :(得分:0)

感谢大家的帮助。

我找到了答案,MySQL 5.6和MariaDB如何选择数据之间存在细微差别。

SELECT 
    *
FROM
    `users`
        LEFT JOIN
    (SELECT 
        `hours`.`user`, `hours`.`work_type`, `hours`.`project`
    FROM
        `hours`
    WHERE
        hours.id in (SELECT max(`id`) AS `id` from hours where hours.stop is null **GROUP BY hours.user**)  **GROUP BY hours.user**) AS `hours` ON `hours`.`user` = `users`.`id`
WHERE
    `users`.`status` = 1
ORDER BY `users`.`name`;

适用于MySQL和MariaDB

其中:

SELECT 
    *
FROM
    `users`
        LEFT JOIN
    (SELECT 
        `hours`.`user`, `hours`.`work_type`, `hours`.`project`
    FROM
        `hours`
    WHERE
        hours.id in (SELECT max(`id`) AS `id` from hours where hours.stop is null **GROUP BY hours.user**) ) AS `hours` ON `hours`.`user` = `users`.`id`
WHERE
    `users`.`status` = 1
ORDER BY `users`.`name`;

仅适用于MySQL

不同之处在于&#39; GROUP BY&#39;似乎MySQL可以访问所有表数据,其中MariaDB&#39; GROUP BY&#39;只能访问&#39; SELECTED&#39;列。