如何 select 联合表中的非相等列

How to select non-equal columns from joint tables

我有五个 table 需要联合查询。

table的创建如下(为简洁起见,我将post创建一条语句,如果需要复制,重复命令并更改[=52=的名称] 到 t2t3t4t5):

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);