MySQL通过丢失空值来选择/分组
我有以下两个表格:MySQL通过丢失空值来选择/分组,mysql,sql,mariadb,Mysql,Sql,Mariadb,我有以下两个表格: > select * from t1; +-------+-------+ | text1 | text2 | +-------+-------+ | a | NULL | | b | c | | d | e | +-------+-------+ > select * from t2; +-------+-------+-------+ | text1 | text2 | value | +-------+------
> 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 |
+-------+-------+-------+
我要做的是将两个表连接在一起,获取t1中每个text1和text2组合的最小值
以下是我到目前为止的查询结果:
> 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值,因为text2是空的。以下是我期待的结果:
+-------+-------+------------+
| text1 | text2 | min(value) |
+-------+-------+------------+
| a | NULL | 1 |
| b | c | 1 |
| d | e | 3 |
+-------+-------+------------+
那么,过滤掉这些空值的查询有什么问题
请注意,t2可能有text1和text2的其他组合,例如我不希望在结果中出现的“a”和“z”,因此我的GROUPBY子句中同时包含text1和text2。至少,这是我想要的,很明显,有些东西并没有像我希望的那样工作
注意,我使用的是MariaDB版本10.3.8,尝试加入空安全操作符
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的行不匹配,因此不会进入结果。我认为自然连接是问题所在
自然联接是内部联接的一种变体,其中联接条件隐含在两个表的公共列上。在您的情况下,自然联接中的查询可以按如下方式编写,它不会返回任何结果,因为它将尝试同时匹配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
不能在此处使用自然连接或使用。改为在ON子句中使用NULL安全运算符,该运算符将NULL计算为1,而NULL=NULL为NULL:
演示:谢谢。我不得不把它交给sticky bit因为他在你之前就有了详细的解释。该死的差一点!
select t1.*
from table1 t1
inner join table2 t2
on t1.text1 = t2.text1 and t1.text2 = t2.text2
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;