简体   繁体   English

没有WHERE子句的MySQL LEFT JOIN不返回空行

[英]MySQL LEFT JOIN without WHERE clause returns no null rows

EDIT: Here's my table: 编辑:这是我的桌子:

CREATE TABLE IF NOT EXISTS `punch` (
  `name` varchar(50) NOT NULL,
  `date` varchar(50) NOT NULL,
  `duration` int(11) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

INSERT INTO `punch` (`name`, `date`, `duration`) VALUES
('foo', '1', 2),
('bar', '1', 3),
('bar', '2', 5),
('foo', '3', 6),
('foo', '4', 8),
('bar', '4', 9);

I have table with values below: 我有下面的值表:

SELECT * FROM `punch` P1 WHERE P1.date BETWEEN 1 AND 3 ORDER BY P1.name , date;

result: 结果:

name    date    duration
bar        1    3
bar        2    5
foo        1    2
foo        3    6

I want to make a report for date 1 until 3 like this: 我想为日期1到3制作一个报告,如下所示:

name    date    duration
bar        1    3
bar        2    5
bar        3    null
foo        1    2
foo        2    null
foo        3    6

I tried this query (note the commented WHERE): 我尝试了此查询(请注意注释的WHERE):

SELECT * FROM (
    SELECT DISTINCT date FROM punch WHERE date BETWEEN 1 AND 3
) P1
LEFT JOIN (
    SELECT * FROM punch -- WHERE name = 'bar'
) P2 ON P1.date=P2.date

ORDER BY P2.name, P1.date

I got result: 我得到了结果:

date    name    date    duration
1       bar     1       3
2       bar     2       5
1       foo     1       2
3       foo     3       6

I was expecting something like: 我期待着这样的事情:

date    name    date    duration
2       NULL    NULL    NULL
3       NULL    NULL    NULL
1       bar     1       3
2       bar     2       5
1       foo     1       2
3       foo     3       6

Now, when I remove the commented WHERE, I got result: 现在,当我删除注释的WHERE时,我得到了结果:

date    name    date    duration
3       NULL    NULL    NULL
1       bar     1       3
2       bar     2       5

My question is, why LEFT JOIN above, behaves like INNER JOIN when there's no WHERE clause? 我的问题是,当没有WHERE子句时,为什么上面的LEFT JOIN表现得像INNER JOIN?

And what is the correct query for my expected report above? 对于我上面的预期报告,正确的查询是什么?

Thanks 谢谢

Hi something like this gonna work:) 嗨,像这样的东西会起作用:)

 SELECT DISTINCT 
    P1.name, 
    P2.date,
    (SELECT PP.duration 
     FROM punch PP 
       WHERE P1.name = PP.name
         AND P2.date = PP.date ) AS duration
    FROM
      (SELECT DISTINCT name FROM  `punch`) P1,
      (SELECT DISTINCT date FROM punch)P2
        WHERE P2.date BETWEEN 1 AND 3
        ORDER BY P1.name , P2.date

Results: 结果:

NAME    DATE    DURATION
bar        1    3
bar        2    5
bar        3    (null)
foo        1    2
foo        2    (null)
foo        3    6

SQLFIDDLE example SQLFIDDLE示例

Try the following: 请尝试以下操作:

SELECT * FROM (
    SELECT DISTINCT date FROM punch WHERE date BETWEEN 1 AND 3
) P1
LEFT OUTER JOIN (
    SELECT * FROM punch  WHERE name = 'bar'
) P2 ON P1.date=P2.date

An OUTER JOIN should answer your issue. OUTER JOIN应回答您的问题。 It includes non-matching elements from the second table. 它包括第二个表中的不匹配元素。

Look here for more info about how it works: http://infogoal.com/sql/sql-outer-join.htm 在此处查找有关其工作方式的更多信息: http : //infogoal.com/sql/sql-outer-join.htm

Create additional table with day numbers and join punch table with this table. 创建带有日期编号的其他表,并将punch表与此表连接。

CREATE TABLE days(day_num INT(11));

INSERT INTO days(day_num) VALUES (1),(2),(3),(4),(5);

Add more records if you need 如果需要,添加更多记录


Result query - 结果查询-

SELECT p.* FROM days d
LEFT JOIN punch p
  ON p.date = d.day_num
WHERE
  d.day_num BETWEEN 1 AND 3
ORDER BY
  p.name, p.date;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM