如何 select 联合表中的非相等列
How to select non-equal columns from joint tables
我有五个 table 需要联合查询。
table的创建如下(为简洁起见,我将post创建一条语句,如果需要复制,重复命令并更改[=52=的名称] 到 t2
、t3
、t4
和 t5
):
CREATE TABLE `t1` (
`id` int(11) NOT NULL,
`name` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
创建 table 之后,我在每个 table 中有 2 行。
t1
数据:
# id, name
'1', 'a'
'2', 'b'
t2
数据:
# id, name
'1', 'a'
'2', 'c'
t3
数据:
# id, name
'1', 'a'
'2', 'd'
t4
数据:
# id, name
'1', 'a'
'2', 'e'
t5
数据:
# id, name
'1', 'a'
'2', 'f'
然后我向 5 table 联合查询。当 name
在所有五个 table 中都不相等时,查询旨在提取行。
查询:
select `t1`.`name` as 't1 name', `t2`.`name` as 't2 name', `t3`.`name` as 't3 name', `t4`.`name` as 't4 name', `t5`.`name` as 't5 name'
from `test`.`t1`
join `test`.`t2` on `t1`.`id` = `t2`.`id`
join `test`.`t3` on `t2`.`id` = `t3`.`id`
join `test`.`t4` on `t3`.`id` = `t4`.`id`
join `test`.`t5` on `t4`.`id` = `t5`.`id`
where not(`t1`.`name` = `t2`.`name` and
`t2`.`name` = `t3`.`name` and
`t3`.`name` = `t4`.`name` and
`t4`.`name` = `t5`.`name`);
我的问题是:
有没有更好的方法来形成 where
语句?我只是觉得这是一个长期的条件。有没有更好的方法来提取名称列在所有 table 中不相等的行?或者这是测试它们是否相等的唯一可能方法?
如果您要求 id
在所有五个 table 中并且要查找不相等的名称,那么 join
是一个合理的方法。您可以使用 least()
和 greatest()
进行比较:
select `t1`.`name` as 't1 name', `t2`.`name` as 't2 name', `t3`.`name` as 't3 name', `t4`.`name` as 't4 name', `t5`.`name` as 't5 name'
from `test`.`t1` join
`test`.`t2`
on `t1`.`id` = `t2`.`id` join
`test`.`t3`
on `t2`.`id` = `t3`.`id` join
`test`.`t4`
on `t3`.`id` = `t4`.`id` join
`test`.`t5`
on `t4`.`id` = `t5`.`id`
where least(t1.name, t2.name, t3.name, t4.name, t5.name) <> greatest(t1.name, t2.name, t3.name, t4.name, t5.name);
如果要查找不在所有五个table中或者名称不同的id
,那么上面的方法是行不通的。为此,使用 union all
并稍微改变 Salman 的方法:
select id, group_concat(distinct name) as names
from ((select id, name, 1 as which from t1) union all
(select id, name, 2 as which from t2) union all
(select id, name, 3 as which from t3) union all
(select id, name, 4 as which from t4) union all
(select id, name, 5 as which from t5)
) t
group by id
having count(distinct which) <> 5 or
min(name) <> max(name);
我有五个 table 需要联合查询。
table的创建如下(为简洁起见,我将post创建一条语句,如果需要复制,重复命令并更改[=52=的名称] 到 t2
、t3
、t4
和 t5
):
CREATE TABLE `t1` (
`id` int(11) NOT NULL,
`name` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
创建 table 之后,我在每个 table 中有 2 行。
t1
数据:
# id, name
'1', 'a'
'2', 'b'
t2
数据:
# id, name
'1', 'a'
'2', 'c'
t3
数据:
# id, name
'1', 'a'
'2', 'd'
t4
数据:
# id, name
'1', 'a'
'2', 'e'
t5
数据:
# id, name
'1', 'a'
'2', 'f'
然后我向 5 table 联合查询。当 name
在所有五个 table 中都不相等时,查询旨在提取行。
查询:
select `t1`.`name` as 't1 name', `t2`.`name` as 't2 name', `t3`.`name` as 't3 name', `t4`.`name` as 't4 name', `t5`.`name` as 't5 name'
from `test`.`t1`
join `test`.`t2` on `t1`.`id` = `t2`.`id`
join `test`.`t3` on `t2`.`id` = `t3`.`id`
join `test`.`t4` on `t3`.`id` = `t4`.`id`
join `test`.`t5` on `t4`.`id` = `t5`.`id`
where not(`t1`.`name` = `t2`.`name` and
`t2`.`name` = `t3`.`name` and
`t3`.`name` = `t4`.`name` and
`t4`.`name` = `t5`.`name`);
我的问题是:
有没有更好的方法来形成 where
语句?我只是觉得这是一个长期的条件。有没有更好的方法来提取名称列在所有 table 中不相等的行?或者这是测试它们是否相等的唯一可能方法?
如果您要求 id
在所有五个 table 中并且要查找不相等的名称,那么 join
是一个合理的方法。您可以使用 least()
和 greatest()
进行比较:
select `t1`.`name` as 't1 name', `t2`.`name` as 't2 name', `t3`.`name` as 't3 name', `t4`.`name` as 't4 name', `t5`.`name` as 't5 name'
from `test`.`t1` join
`test`.`t2`
on `t1`.`id` = `t2`.`id` join
`test`.`t3`
on `t2`.`id` = `t3`.`id` join
`test`.`t4`
on `t3`.`id` = `t4`.`id` join
`test`.`t5`
on `t4`.`id` = `t5`.`id`
where least(t1.name, t2.name, t3.name, t4.name, t5.name) <> greatest(t1.name, t2.name, t3.name, t4.name, t5.name);
如果要查找不在所有五个table中或者名称不同的id
,那么上面的方法是行不通的。为此,使用 union all
并稍微改变 Salman 的方法:
select id, group_concat(distinct name) as names
from ((select id, name, 1 as which from t1) union all
(select id, name, 2 as which from t2) union all
(select id, name, 3 as which from t3) union all
(select id, name, 4 as which from t4) union all
(select id, name, 5 as which from t5)
) t
group by id
having count(distinct which) <> 5 or
min(name) <> max(name);