MySQL SELECT / GROUP BY丢失NULL

时间:2018-08-02 16:13:22

标签: mysql sql mariadb

我有以下两个表:

> select * from t1;
+-------+-------+
| text1 | text2 |
+-------+-------+
| a     | NULL  |
| b     | c     |
| d     | e     |
+-------+-------+

> select * from t2;
+-------+-------+-------+
| text1 | text2 | value |
+-------+-------+-------+
| a     | NULL  |     1 |
| a     | NULL  |     2 |
| a     | NULL  |     3 |
| b     | c     |     1 |
| b     | c     |     2 |
| d     | e     |     3 |
| f     | g     |     1 |
+-------+-------+-------+

我想要做的是将两个表连接在一起,为value中的每个text1,text2组合获取最小的t1

这是我到目前为止的查询,得到的结果是

> select text1, text2, min(value)
> from t1
> natural join t2
> group by text1, text2
> order by text1 asc;
+-------+-------+------------+
| text1 | text2 | min(value) |
+-------+-------+------------+
| b     | c     |          1 |
| d     | e     |          3 |
+-------+-------+------------+

所以这几乎是我所需要的,但是正如您所看到的,我丢失了a值,因为text2NULL。这是我期望的结果:

+-------+-------+------------+
| text1 | text2 | min(value) |
+-------+-------+------------+
| a     | NULL  |          1 |
| b     | c     |          1 |
| d     | e     |          3 |
+-------+-------+------------+

那我的查询过滤出了这些NULL值又有什么问题呢?

请注意,t2可以具有text1text2的其他组合,例如('a','z'),我不想要,但为什么我的text1子句中同时包含text2GROUP BY。至少,这就是我要的(显然有些东西无法正常工作。)

注意,我使用的是MariaDB 10.3.8版

3 个答案:

答案 0 :(得分:2)

尝试加入<=>空安全运算符。

SELECT t1.text1,
       t1.text2,
       min(t2.value)
       FROM t1
            INNER JOIN t2
                       ON t2.text1 <=> t1.text1
                          AND t2.text2 <=> t1.text2
       GROUP BY t1.text1,
                t1.text2
       ORDER BY t1.text1 ASC;

您当前拥有的翻译为:

SELECT t1.text1,
       t1.text2,
       min(t2.value)
       FROM t1
            INNER JOIN t2
                       ON t2.text1 = t1.text1
                          AND t2.text2 = t1.text2
       GROUP BY t1.text1,
                t1.text2
       ORDER BY t1.text1 ASC;

由于NULL = NULL不正确,具有null的行不匹配,因此不将其计入结果。

答案 1 :(得分:2)

您不能在此处使用NATURAL JOINUSING()。改为在ON子句中使用NULL安全运算符<=>,它将NULL <=> NULL评估为1,而NULL = NULLNULL

select t1.text1, t1.text2, min(value)
from t1
join t2
  on  t2.text1 = t1.text1
  and t2.text2 <=> t1.text2
group by t1.text1, t1.text2
order by t1.text1 asc;

演示:http://sqlfiddle.com/#!9/3ca2a1/1

答案 2 :(得分:0)

我认为natural join是问题

自然联接是INNER JOIN的变体,其中联接条件在两个表的公共列上都是隐式的。就您而言,自然联接中的查询可以编写如下,由于它将尝试同时匹配A和B,因此不会返回任何结果

select *
from table1
natural join table2

同样可以在内部联接中编写,如下所示

select t1.*
from table1 t1
inner join table2 t2
on t1.text1 = t2.text1 and t1.text2 = t2.text2