我有以下两个表:
> 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
值,因为text2
是NULL
。这是我期望的结果:
+-------+-------+------------+
| text1 | text2 | min(value) |
+-------+-------+------------+
| a | NULL | 1 |
| b | c | 1 |
| d | e | 3 |
+-------+-------+------------+
那我的查询过滤出了这些NULL
值又有什么问题呢?
请注意,t2
可以具有text1
和text2
的其他组合,例如('a','z')
,我不想要,但为什么我的text1
子句中同时包含text2
和GROUP BY
。至少,这就是我要的(显然有些东西无法正常工作。)
注意,我使用的是MariaDB 10.3.8版
答案 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 JOIN
或USING()
。改为在ON子句中使用NULL安全运算符<=>
,它将NULL <=> NULL
评估为1
,而NULL = NULL
为NULL
:
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;
答案 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