从两列中选择不同的组合

17

我有一个名为Hyperlink的表格,其中有两列source和destination,用于存储超链接的源和目标。

source | destination 
-------------------- 
  a    |  b 
  b    |  c 
  c    |  d 
  c    |  b 

有两个超链接分别涉及到b和c。这两个超链接之间的区别在于超链接的方向。但是,我的目标是检索唯一的超链接,无论方向如何。因此,对于从b到c和从c到b的超链接,我只想选择其中一个。任何一个都可以。

所以我的结果应该是这样的:

source | destination 
-------------------- 
  a    |  b 
  b    |  c 
  c    |  d 

目前我能在Java中实现这一点,在使用JDBC执行SQL语句之前进行一些处理。然而,当表变得非常大时,这将非常繁琐。

我想知道是否有办法可以在SQL中完成这个任务。

我尝试了SELECT DISTINCT source,destination FROM Hyperlink,但它返回了唯一的排列组合。我需要唯一的组合。

谢谢!


2
如果您发布代码、XML或数据示例,请在文本编辑器中突出显示这些行,并单击编辑器工具栏上的“代码示例”按钮( {})以使其格式化和语法高亮!然后,您就不需要任何混乱的<br>&nbsp;标记了! - marc_s
2
太好了,谢谢你的提示!使用混乱的标签确实很困难。 - paperclip
4个回答

4

最小值(least())和最大值(greatest())操作符可以轻松实现此目标,但由于MySQL不支持它们,您需要使用CASE结构来获取较小/较大的值。如果只有两列,那么这是可行的,但一旦涉及到更多列,这个解决方案就会变得非常混乱。

select distinct 
          case 
            when source < destination then source 
            else destination 
          end as source,
          case 
            when source > destination then source 
            else destination 
          end as destination
from hyperlinks

这个对我有用。我只使用两列,所以这个解决方案已经足够好了。谢谢! - paperclip

2
请尝试以下查询:
SELECT DISTINCT source, destination FROM hyperlink
MINUS 
SELECT destination, source FROM hyperlinks WHERE source < destination;

如果你正在使用PostgreSQL、DB2或TSQL,使用EXCEPT关键字代替MINUS。这适用于Oracle。

编辑:在MySQL中没有这些关键字的等价物。你将不得不按照Jim Riordan所建议的选择值进行处理。如果有人需要在其他四个主要的数据库管理系统中执行此操作,我将不会删除我的回答。


我正在使用MySQL,但还是谢谢你的回答。如果没有错的话,在MySQL中应该使用UNION而不是MINUS。再次感谢! - paperclip
据我所知,UNION 将表中的行合并并删除重复项。这是不同的。MINUS 是一种集合操作,它从另一个集合中每个相同的行中删除一个行。(A, B, C) UNION (C, D) 得到 (A, B, C, D)。但是 (A, B, C) MINUS (C, D) 返回 (A, B)。你不能仅仅用一个替换另一个,你必须显著修改 SELECT 语句。 - toniedzwiedz

1

您可以像下面这样使用两个单独的连接查询的联合:

SELECT
lhs.source, lhs.destination
FROM Hyperlink lhs
LEFT OUTER JOIN Hyperlink rhs
ON rhs.source = lhs.destination
WHERE rhs.source IS NULL
UNION
SELECT
lhs.source, lhs.destination
FROM Hyperlink lhs
JOIN Hyperlink rhs
ON rhs.source = lhs.destination
WHERE rhs.destination <> lhs.source
ORDER BY source;

第一个查询获取没有源作为目标的链接,第二个查询获取源作为目标但有不同对立面的匹配项。这可能不是最快的实现方式,但确保在源和目标列上有索引将有所帮助,它是否对您的性能有影响取决于Hyperlink表的大小或可能的大小。

0
我尝试了这个查询,它对我起作用了。
SELECT table1.Source, table1.Destination FROM dbo.hyperlinks table1 WHERE NOT EXISTS
(SELECT * FROM hyperlinks table2 WHERE table1.Source = table2.Destination AND table2.Source = table1.Destination)

UNION 

SELECT TOP 1 table1.Source, table1.Destination FROM hyperlinks table1 WHERE 
  (SELECT COUNT(*) FROM hyperlinks table2 WHERE table1.Source = table2.Destination AND  table2.Source = table1.Destination) > 0

我不理解你的陈述。table2是从哪里来的? - paperclip
这是一个超链接表的别名!因为在我的查询中我使用了多个超链接表,所以我必须为其使用一个别名。我使用了 test1 和 test2,你可以使用任何你想要的名称! - Azadeh Radkianpour

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接