SQL Server 关联交叉引用表

fcwjkofz  于 2023-02-03  发布在  其他
关注(0)|答案(1)|浏览(155)

我有一个如下所示的SQL表,其中一个值链接到第二个值,反之亦然。
| 世界其他地区|识别码1|识别码2|
| - ------|- ------|- ------|
| 1个|1个|第二章|
| 第二章|第二章|1个|
| 三个|三个|四个|
| 四个|四个|三个|
....
这可能是一些糟糕的设计,但这是我坚持的。我需要在SQL Server中生成一个SQL查询,只返回以下内容(顺序无关紧要):
| 世界其他地区|识别码1|识别码2|
| - ------|- ------|- ------|
| 1个|1个|第二章|
| 三个|三个|四个|
....

| 世界其他地区|识别码1|识别码2|
| - ------|- ------|- ------|
| 第二章|第二章|1个|
| 四个|四个|三个|
....
我有一个ID列表(1,2,3,4),我用它来查询ID1字段或ID2字段的表,但它总是返回所有行,因为这些ID存在于两列中。
我试过通过查看一个字段是否存在于另一列中来消除一行,但显然没有结果。
一个可行的解决方案是查看rownum字段,只获取偶数行或奇数行,但这感觉有点奇怪,而且该列表中可能有其他值,而不是IN列表的一部分,因此可能会遗漏一些行?
从TSQL的Angular 考虑任何有说服力的问题

e5nqia27

e5nqia271#

这里有一个(相当麻烦但相当有效)的方法。
首先,创建并填充示例表(在以后的问题中为我们保存此步骤):

CREATE TABLE Table1 (
  [ROW] int, 
  [ID1] int, 
  [ID2] int
);
    
INSERT INTO Table1 ([ROW], [ID1], [ID2]) VALUES
(1, 1, 2),
(2, 2, 1),
(3, 3, 4),
(4, 4, 3),
(5, 1, 4);

注意:最后一个原始数据不是您提供的示例数据的一部分,但我假设您还希望在结果记录中包括只有一行在Id1和Id2之间具有连接的记录。
然后,使用一对公共表表达式来获得任意对Id1和Id2的最小行数,而不管id的顺序,然后查询连接到第二个cte的原始表:

WITH CTE1 AS 
(
    SELECT Row, 
           IIF(Id1 < Id2, Id1, Id2) As Small,
           IIF(Id1 < Id2, Id2, Id1) As Big
    FROM Table1
), CTE2 AS 
(
    SELECT Min(Row) As MinRow
    FROM CTE1
    GROUP BY Small, Big
)

SELECT Row, Id1, Id2
FROM Table1
JOIN CTE2
    ON Row = MinRow;

结果:

Row Id1 Id2
1   1   2
3   3   4
5   1   4

您可以在DB<>Fiddle上观看现场演示

相关问题