在 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:

请注意,GREATESTLEAST 不在 SQL 标准中,但在 一个共同的扩展。其他一些数据库使它们返回NULL(如果有) 参数是NULL,而不是仅当所有参数都是NULL

如果可以NULL 值,您可能需要适应。

【讨论】:

虽然你说 GREATEST/LEAST 与 SQL Server 不兼容。我喜欢你的方法,因为它的效率和简单性。就我个人而言,我认为 MIN/MAX 更简单明了,但 DISTINCT GREATEST 远优于硬编码 switch 语句方法。它还处理最小值/最大值不处理的 varchar(x)。并且来自拥有超过 100K 状态点的人......一切都不会丢失。 @AdrianWhite:请注意,Postgres 也会在 CASEmin()/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 中查找唯一的路由的主要内容,如果未能解决你的问题,请参考以下文章

如何延迟铁路由器路由查找

捕获打开或创建文件的请求并重新路由它

路由器的MAC地址是全球唯一的吗

路由器根据IP报文中的目的IP地址还是源IP地址进行路由的查找,掩码最长匹配还掩码最短匹配

在DRF路由器中更改查找正则表达式

使用命令行查找丢失的 URL 路由