1

您好,我有如下表格:

Table: port 
tid    leftside    rightside 
1      2           3          
2      3           2
3      2           4
4      4           2
5      4           3
6      3           4
7      4           5
8      5           4
9      3           6
10     6           3

当我运行这个查询

SELECT * 
FROM port pt JOIN port p 
  ON (pt.leftside = p.rightside 
     and p.leftside <> 2) 
WHERE pt.rightside = 2

我得到了这个结果

tid    leftside    rightside 
6      3           4 
5      4           3
8      5           4
10     6           3

前两行表示相同的关系,尽管它们位于相对的两侧。如果有重复的记录,我希望我的查询只检索一行。例如:查询应返回以下行

tid    leftside    rightside 
6      3           4

代替

tid    leftside    rightside 
6      3           4 
5      4           3

这些行。

4

2 回答 2

0

另一种方法是交换leftsiderightside只要leftside大于rightside。然后使用PARTITION BYandRANK删除重复项:

SELECT tid,
       leftside,
       rightside
FROM
(
  SELECT p.tid,
         CASE WHEN p.leftside <= p.rightside
              THEN p.leftside
              ELSE p.rightside
         END AS leftside,
         CASE WHEN p.leftside > p.rightside
              THEN p.leftside
              ELSE p.rightside
         END AS rightside,
         RANK() OVER
         (PARTITION BY CASE WHEN p.leftside <= p.rightside
                            THEN p.leftside
                            ELSE p.rightside
                       END,
                       CASE WHEN p.leftside > p.rightside
                            THEN p.leftside
                            ELSE p.rightside
                       END
          ORDER BY p.tid ASC) AS rank
  FROM port pt JOIN port p 
    ON (pt.leftside = p.rightside
        AND p.leftside <> 2)
  WHERE pt.rightside = 2  
) subquery
WHERE rank = 1;

请参阅SQL Fiddle 演示

于 2013-03-15T13:42:10.663 回答
0

我在 MS SQL 中玩过它

with port as
(
select 1 as tid, 2 as leftside, 3 as rightside
UNION ALL
select 2, 3, 2
UNION ALL
select 3, 2, 4
UNION ALL
select 4, 4, 2
UNION ALL
select 5, 4, 3
UNION ALL
select 6, 3, 4
UNION ALL
select 7, 4, 5
UNION ALL
select 8, 5, 4
UNION ALL
select 9, 3, 6
UNION ALL
select 10, 6, 3
)
SELECT * 
FROM port pt JOIN port p 
  ON (pt.leftside = p.rightside 
     and p.leftside <> 2) 
WHERE pt.rightside = 2

并得到了这些结果-

(pt.tid pt.leftside pt.rightside p.tid p.leftside p.rightside)
2   3   2   5   4   3
4   4   2   6   3   4
4   4   2   8   5   4
2   3   2   10  6   3

in (subquery)通过在 WHERE 子句中添加一个...

SELECT *
FROM port pt JOIN port p 
  ON (pt.leftside = p.rightside 
    and p.leftside <> 2) 
WHERE (pt.rightside = 2)
   AND p.tid in (SELECT max(chk.tid) FROM port chk
                 GROUP BY Case when leftside>rightside
                             then rightside else leftside end,
                          Case when leftside<rightside
                             then rightside else leftside end
                )

它摆脱了 p.tid=5 的行,因为它不是匹配对的较高(最大值)值。

解释:这列出了所有 10 行,左侧和右侧按低/高顺序排列。

SELECT tid,
  Case when leftside>rightside then rightside else leftside end as lower,
  Case when leftside<rightside then rightside else leftside end as higher
FROM port

因此,通过对 lower&higher 进行 GROUPing,并检索 max(tid),我们得到匹配对的较高 tid。

于 2013-03-15T13:05:02.953 回答