我有一张这样的表:
id | t1 | t2
---------------
1 | a | b
2 | c | a
3 | a | e
4 | f | g
5 | c | c
Run Code Online (Sandbox Code Playgroud)
我想比较列t1
并t2
相互比较以删除匹配值并在每列中获取唯一值,如下所示:
t1 | t2
-----------
a | b
c | null
null | e
f | g
null| null
Run Code Online (Sandbox Code Playgroud)
选择哪一行显示值以及其他哪一行显示空值并不重要。例如,由于a
在原始数据集的第 3 行中也找到了值,因此以下输出也将有效:
t1 | t2
-----------
null | b
c | null
a | e
f | g
null| null
Run Code Online (Sandbox Code Playgroud)
最终目标是在两列中显示所有不同的值并且没有相同的值。
如果没有窗口函数,这在 MySQL 中非常困难。由于两列 -t1
和t2
- 存储相似的内容,并且您只需要两列不同的值,因此在单个列中获取值会容易得多:
select t1 as tx from t
union distinct
select t2 from t ;
Run Code Online (Sandbox Code Playgroud)
我看不出有任何理由获得原始的复杂结果,除非您想保留表中其他列的信息并只从这 2 列中删除重复项。在这种情况下, anUPDATE
会更有意义。
无论如何,这是一种获得此结果的方法。它假设(id)
有一个UNIQUE
约束。在dbfiddle.uk测试:
select t.id, gt1.tx as t1, gt2.tx as t2
from t
left join
( select ut.tx, min(ut.id) as id
from
( select id, t1 as tx from t
union all
select id, t2 from t
) ut
group by ut.tx
) as gt1
on t.t1 = gt1.tx and t.id = gt1.id
left join
( select ut.tx, min(ut.id) as id
from
( select id, t1 as tx from t
union all
select id, t2 from t
) ut
group by ut.tx
) as gt2
on t.t2 = gt2.tx and t.id = gt2.id and gt1.tx <> gt2.tx
;
Run Code Online (Sandbox Code Playgroud)
请注意,在具有 CTE 的 MariaDB(MySQL 的第一个表兄弟)中,可以更紧凑、更清晰地重写相同的查询:
with gt as
( select ut.tx, min(ut.id) as id
from
( select id, t1 as tx from t
union all
select id, t2 from t
) ut
group by ut.tx
)
select t.id, gt1.tx as t1, gt2.tx as t2
from t
left join gt as gt1
on t.t1 = gt1.tx and t.id = gt1.id
left join gt as gt2
on t.t2 = gt2.tx and t.id = gt2.id and gt1.tx <> gt2.tx
;
Run Code Online (Sandbox Code Playgroud)
不过,从逻辑上讲,这两种变体的工作方式相同。这个子选择:
( select ut.tx, min(ut.id) as id
from
( select id, t1 as tx from t
union all
select id, t2 from t
) ut
group by ut.tx
)
Run Code Online (Sandbox Code Playgroud)
返回所有不同t1
和t2
与第一的ID一起值1行,其中每个遇到。对于您的示例,它会产生以下输出:
tx id
--- ---
a 1
b 1
c 2
e 3
f 4
g 4
Run Code Online (Sandbox Code Playgroud)
上面的集合与原始表连接了两次, ont1
和 on t2
。在每种情况下,如果原始行的 ID 与子选择行的 ID 匹配,则该值将原封不动地返回,因为匹配表明该行是该值的第一次出现;否则该值将被替换为空值。
1 ID 顺序为“第一个”。
归档时间: |
|
查看次数: |
1718 次 |
最近记录: |