LEFT JOIN没有得到理想的结果

时间:2015-03-13 09:55:36

标签: mysql

所以我有2个表,第一个表是clock_in_out我从这个表中选择登录和登出日期。第二个表打破我选择进出字段。 clock_in_out中可能存在与break表不匹配的fiedls ...我在user_id上加入它们。

问题是我只在中断具有匹配字段时才获得结果,我认为左连接将获取左表中的所有数据,并使用带有NULL的伪行来表示非匹配数据。

以下是我的询问:

SELECT `clock_in_out`.`loggedin`, `clock_in_out`.`loggedout`, `breaks`.`in`, 
      `breaks`.`out` FROM (`clock_in_out`) 
LEFT JOIN `breaks` ON `clock_in_out`.`user_id` = `breaks`.`user_id`      
WHERE 
      `clock_in_out`.`user_id` = 47 
      AND `breaks`.`user_id` = 47 
      AND `clock_in_out`.`loggedin` LIKE "%2015-03-13%" 
      AND `clock_in_out`.`loggedout` LIKE "%2015-03-13%" 
      AND `breaks`.`in` LIKE "%2015-03-13%"
      AND `breaks`.`out` LIKE "%2015-03-13%"

我正在使用CodeIgniter准备好的查询语句,我不确定如何使用它们获得所需的结果:这就是我所拥有的:

    $this->db->select('clock_in_out.loggedin, clock_in_out.loggedout, breaks.in, breaks.out');
    $this->db->from('clock_in_out');

    $this->db->join('breaks','clock_in_out.user_id = breaks.user_id', 'LEFT');

    $this->db->like('breaks.in', $today);
    $this->db->like('breaks.out', $today);
    $this->db->where('clock_in_out.user_id = '.$user_id);
    $this->db->like('clock_in_out.loggedin', $today);
    $this->db->like('clock_in_out.loggedout', $today);

    $q = $this->db->get();

这会产生:

SELECT `clock_in_out`.`loggedin`, `clock_in_out`.`loggedout`, `breaks`.`in`, `breaks`.`out` FROM (`clock_in_out`)
LEFT JOIN `breaks` ON `clock_in_out`.`user_id` = `breaks`.`user_id`
WHERE `clock_in_out`.`user_id` = 47
AND `breaks`.`in` LIKE '%2015-03-13%'
AND `breaks`.`out` LIKE '%2015-03-13%'
AND `clock_in_out`.`loggedin` LIKE '%2015-03-13%' AND `clock_in_out`.`loggedout` LIKE '%2015-03-13%'

根据CI答案编辑生成的查询:

SELECT `clock_in_out`.`loggedin`, `clock_in_out`.`loggedout`, `breaks`.`in`, `breaks`.`out` FROM (`clock_in_out`)
LEFT JOIN `breaks` ON `clock_in_out`.`user_id` = `breaks`.`user_id`
WHERE `clock_in_out`.`user_id` = 47 
AND `clock_in_out`.`loggedin` LIKE '%2015-03-13%' 
AND `clock_in_out`.`loggedout` LIKE '%2015-03-13%'

此致

3 个答案:

答案 0 :(得分:4)

您只能从break表中获取匹配的字段,因为您在WHERE内使用它。试试这个:

SELECT `clock_in_out`.`loggedin`, `clock_in_out`.`loggedout`, `breaks`.`in`, 
      `breaks`.`out` FROM (`clock_in_out`) 
LEFT JOIN `breaks` ON 
      `clock_in_out`.`user_id` = `breaks`.`user_id`    
      AND `breaks`.`in` LIKE "%2015-03-13%"
      AND `breaks`.`out` LIKE "%2015-03-13%"
WHERE 
      `clock_in_out`.`user_id` = 47 
      AND `clock_in_out`.`loggedin` LIKE "%2015-03-13%" 
      AND `clock_in_out`.`loggedout` LIKE "%2015-03-13%" 

CodeIgniter的更新

确保$today已正确转义以避免SQL注入。

    $this->db->select('clock_in_out.loggedin, 
                       clock_in_out.loggedout,
                       breaks.in, 
                       breaks.out');
    $this->db->from('clock_in_out');

    $this->db->join('breaks','clock_in_out.user_id = breaks.user_id 
                AND `breaks`.`in` LIKE "%'.$today.'%" 
                AND `breaks`.`out` LIKE "%'.$today.'%"', 'LEFT');

    $this->db->where('clock_in_out.user_id = '.$user_id);
    $this->db->like('clock_in_out.loggedin', $today);
    $this->db->like('clock_in_out.loggedout', $today);

    $q = $this->db->get()

答案 1 :(得分:2)

LEFT JOIN执行您所说的内容(选择左表中的所有行,当右表中没有匹配时,将它们与NULL s的行配对。)

然后WHERE条件来过滤联接集。您在右侧表格(WHERE)字段上的breaks条件会过滤掉这些字段上具有NULL值的行。

答案 2 :(得分:0)

只需删除breaks的条件。user_id = 47

SELECT 
`clock_in_out`.`loggedin`,
`clock_in_out`.`loggedout`, 
`breaks`.`in`, 
`breaks`.`out` 
FROM (`clock_in_out`) 
LEFT JOIN `breaks` ON `clock_in_out`.`user_id` = `breaks`.`user_id`
WHERE 
`clock_in_out`.`user_id` = 47 
AND `clock_in_out`.`loggedin` LIKE "%2015-03-13%" 
AND `clock_in_out`.`loggedout` LIKE "%2015-03-13%" 
AND (`breaks`.`in` LIKE "%2015-03-13%"  or `breaks`.`in` is null )
AND (`breaks`.`out` LIKE "%2015-03-13%" or `breaks`.`out` is null)