在 sql 中查找唯一的路由
Posted
技术标签:
【中文标题】在 sql 中查找唯一的路由【英文标题】:Find unique routes in sql 【发布时间】:2021-07-03 17:34:18 【问题描述】:我有一个包含 2 列、源和目标的表路由。我想找出独特的路线。
Sample Input for route table -
-------------
src dest
-------------
A B
C D
B A
D C
Required output -
-------------
src dest
-------------
A B
C D
在这种情况下,AB 和 BA 是同一条路由,只是 src 和 dest 发生了变化,所以我们只在输出中显示一次。解决此问题的任何输入都会有所帮助。
【问题讨论】:
只标记您使用的数据库。 到目前为止你在做什么,你遇到了什么问题? 【参考方案1】:一个小逻辑开关就可以了
示例
Select Distinct
case when src < dest then src else dest end as src
, case when src < dest then dest else src end as dest
From YourTable
结果
src dest
A B
C D
【讨论】:
这是一个很好的答案,但 (1) 如果所有对都在具有逆元的数据中,则它不是最优的;(2) 如果不是,则结果可能不是原始数据中的对。 【参考方案2】:我建议:
select src, dest
from t t2
where src < dest or
not exists (select 1 from t t2 where t2.src < t2.dest and t2.src = t.dest and t2.dest = t.src);
注意:这保证只返回表中的对。如果您知道所有“反转”都在表中(如在您的示例数据中),那么它就是:
select src, dest
from t
where src < dest;
【讨论】:
这会比仅仅对 ascii 求和更快吗 @AdrianWhite。 . .我不知道那条评论是什么意思。 @AdrianWhite 和戈登。也许这将消除混乱。 dbfiddle.uk/… @JohnCappelletti 。 . .谢谢你。我修正了我的答案,所以它不再是荒谬的。 @JohnCappelletti 。 . .我很感激——非常感激。然而,最初的答案只是我想要的一半。我省略了相关性子句。对我来说,“想出答案”是不够的。我还需要以某种可以理解的形式把它弄出来!【参考方案3】:GREATEST
and LEAST
最简单:
SELECT DISTINCT GREATEST(src, dest) AS a, LEAST(src, dest) AS b
FROM tbl;
逻辑上等价于John's answer 和CASE
,除了 用于其中一个是NULL
的极端情况。在 Postgres 中,您使用此查询两次获得非空值。 Quoting the manual:
请注意,
GREATEST
和LEAST
不在 SQL 标准中,但在 一个共同的扩展。其他一些数据库使它们返回NULL
(如果有) 参数是NULL
,而不是仅当所有参数都是NULL
。
如果可以有NULL
值,您可能需要适应。
【讨论】:
虽然你说 GREATEST/LEAST 与 SQL Server 不兼容。我喜欢你的方法,因为它的效率和简单性。就我个人而言,我认为 MIN/MAX 更简单明了,但 DISTINCT GREATEST 远优于硬编码 switch 语句方法。它还处理最小值/最大值不处理的 varchar(x)。并且来自拥有超过 100K 状态点的人......一切都不会丢失。 @AdrianWhite:请注意,Postgres 也会在CASE
或 min()
/max()
中处理 varchar(x)
,因为为该类型定义了所需的运算符。 GREATEST
/LEAST
更简单。甚至没有更快,如果有的话。【参考方案4】:
使用 ascii 函数可以让优化器和 sql 中的视觉效果更好。
select
min(src) src
,max(dst) dst
from
cte
group by
(ascii(src) + ascii(dst))
旁注假设 src/dst 是 char(1),如问题所示。如果这变成了 varchar(x),那么我会将 varchar() 中的所有 ascii 相加,如 this SO answer
中所示【讨论】:
以上是关于在 sql 中查找唯一的路由的主要内容,如果未能解决你的问题,请参考以下文章