MySQL - select 来自两列的不同值
MySQL - select distinct value from two column
我有一个 table 结构如下:
IdM|IdS
-------
1 | 2
1 | 3
1 | 4
2 | 1
2 | 3
2 | 4
3 | 1
3 | 2
3 | 3
3 | 4
我如何在这个 table 上做一个 select 声明,这将 return 这个 table 的一些行,在每一行中,一个特定的 id 出现只有一个,不管它指定在哪一列?
对于上述结果集,我想要一个 return:
的查询
-------
1 | 2
3 | 4
-------
再举一个例子,如果您要省略原始数据集中的第一行:
IdM|IdS
-------
1 | 3
1 | 4
2 | 1
2 | 3
2 | 4
3 | 1
3 | 2
3 | 3
3 | 4
结果集应该是:
-------
1 | 3
2 | 4
-------
这实际上是一个有趣的问题。如果我没听错,你想遍历数据集并只保留两个值以前从未见过的行。您可以使用递归查询:
with recursive
data as (
select idm, ids, row_number() over(order by idm, ids) rn
from mytable
where idm <> ids
),
cte as (
select idm, ids, rn, 1 as to_keep , concat(idm, ',', ids) visited from data where rn = 1
union all
select d.idm, d.ids, d.rn,
(not find_in_set(d.idm, c.visited) and not find_in_set(d.ids, c.visited)),
case when (not find_in_set(d.idm, c.visited) and not find_in_set(d.ids, c.visited))
then concat_ws(',', c.visited, d.idm, d.ids)
else c.visited
end
from cte c
inner join data d on d.rn = c.rn + 1
)
select idm, ids from cte where to_keep
第一个 CTE 枚举按两列排序的行。然后递归查询遍历结果集,检查两个值是否都是新的,并根据列设置一个标志。保留标记的数字以用于在以下迭代中进行过滤。
请注意,根据您的要求,并非所有值都可能出现在结果集中。考虑以下数据集:
idm ids
+-----+---
1 2
1 3
1 4
您的逻辑只会 return 第一行。
我有一个 table 结构如下:
IdM|IdS
-------
1 | 2
1 | 3
1 | 4
2 | 1
2 | 3
2 | 4
3 | 1
3 | 2
3 | 3
3 | 4
我如何在这个 table 上做一个 select 声明,这将 return 这个 table 的一些行,在每一行中,一个特定的 id 出现只有一个,不管它指定在哪一列?
对于上述结果集,我想要一个 return:
的查询-------
1 | 2
3 | 4
-------
再举一个例子,如果您要省略原始数据集中的第一行:
IdM|IdS
-------
1 | 3
1 | 4
2 | 1
2 | 3
2 | 4
3 | 1
3 | 2
3 | 3
3 | 4
结果集应该是:
-------
1 | 3
2 | 4
-------
这实际上是一个有趣的问题。如果我没听错,你想遍历数据集并只保留两个值以前从未见过的行。您可以使用递归查询:
with recursive
data as (
select idm, ids, row_number() over(order by idm, ids) rn
from mytable
where idm <> ids
),
cte as (
select idm, ids, rn, 1 as to_keep , concat(idm, ',', ids) visited from data where rn = 1
union all
select d.idm, d.ids, d.rn,
(not find_in_set(d.idm, c.visited) and not find_in_set(d.ids, c.visited)),
case when (not find_in_set(d.idm, c.visited) and not find_in_set(d.ids, c.visited))
then concat_ws(',', c.visited, d.idm, d.ids)
else c.visited
end
from cte c
inner join data d on d.rn = c.rn + 1
)
select idm, ids from cte where to_keep
第一个 CTE 枚举按两列排序的行。然后递归查询遍历结果集,检查两个值是否都是新的,并根据列设置一个标志。保留标记的数字以用于在以下迭代中进行过滤。
请注意,根据您的要求,并非所有值都可能出现在结果集中。考虑以下数据集:
idm ids
+-----+---
1 2
1 3
1 4
您的逻辑只会 return 第一行。