SQL:查找匹配多行的唯一多列值三元组?

Sir*_*lot 4 sql-server t-sql sql-server-2019

TL;DR:使用 Transact-SQL/SQL Server,如何找到表中与另一列中的某些值集的列值(ColA、ColB、ColC)的单个“解决方案”三元组相匹配的行?

更多信息:假设我有一个与此类似的表(为了获得焦点而删除了 ID 列):

火焰离子化检测器 可乐 科尔B 科尔C
1 1 1 1
1 2 2 2
2 1 1 1
2 3 3 3
3 1 1 1
3 2 2 2

我试图找到 FID 的每个值都存在的 (ColA、ColB、ColC) 的共同三元组值。在此示例中,(1, 1, 1) 将是该三元组,因此我想返回类似以下内容的内容:

火焰离子化检测器 可乐 科尔B 科尔C
1 1 1 1
2 1 1 1
3 1 1 1

感觉应该是某种使用的集合操作intersect,但我对如何最好地以声明方式对其进行建模和编码感到困惑。想法?非常感谢您的帮助!

澄清:几点希望有助于解释我的问题。

  1. 我正在寻找一个查询来查找三元组可能是什么。我不一定知道数据中的内容。
  2. 三元组值不依赖于 FID 值,反之亦然。我的示例恰好使用了与 FID 值之一匹配的 (1,1,1)。数据可能看起来更像是:
火焰离子化检测器 可乐 科尔B 科尔C
13 1 305 507
13 1 第415章 928
17 号 2 5 57
17 号 1 第415章 928
210 12 305 507
210 1 第415章 928

因此,在本例中,我正在寻找如何编写查询来找出 (1,415,928) 是所有 FID 共有的三元组。

希望这有助于更好地构建我的问题和我正在寻找的内容:)如果您需要更多信息,请告诉我。

Pau*_*ite 7

查找公共元组的一种方法:

DECLARE @T table
(
    FID integer NOT NULL,
    ColA integer NOT NULL,
    ColB integer NOT NULL,
    ColC integer NOT NULL
);

INSERT @T
    (FID, ColA, ColB, ColC)
VALUES
    (13,1,305,507),
    (13,1,415,928),
    (17,2,5,57),
    (17,1,415,928),
    (210,12,305,507),
    (210,1,415,928);

SELECT 
    T.ColA, 
    T.ColB, 
    T.ColC
FROM @T AS T
GROUP BY 
    T.ColA, 
    T.ColB, 
    T.ColC
HAVING COUNT_BIG(*) =
(
    SELECT COUNT_BIG(DISTINCT T2.FID) 
    FROM @T AS T2
);
Run Code Online (Sandbox Code Playgroud)
可乐 科尔B 科尔C
1 第415章 928

返回所有匹配的元组:

SELECT 
    T.FID, 
    T.ColA, 
    T.ColB, 
    T.ColC
FROM @T AS T
WHERE EXISTS
(
    SELECT T.ColA, T.ColB, T.ColC
    INTERSECT
    SELECT T2.ColA, T2.ColB, T2.ColC 
    FROM @T AS T2
    WHERE T2.FID <> T.FID
)
AND NOT EXISTS
(
    SELECT T.ColA, T.ColB, T.ColC
    EXCEPT
    SELECT T3.ColA, T3.ColB, T3.ColC 
    FROM @T AS T3
    WHERE T3.FID <> T.FID
);
Run Code Online (Sandbox Code Playgroud)

或者

SELECT
    T1.FID, T2.ColA, T2.ColB, T2.ColC
FROM
(
    SELECT T2.FID, rc = COUNT_BIG(*) OVER ()
    FROM @T AS T2
    GROUP BY T2.FID
) AS T1
JOIN 
(
    SELECT T.ColA, T.ColB, T.ColC, rc = COUNT_BIG(DISTINCT T.FID)
    FROM @T AS T
    GROUP BY T.ColA, T.ColB, T.ColC
) AS T2
    ON T2.rc = T1.rc;
Run Code Online (Sandbox Code Playgroud)

两者都给出:

火焰离子化检测器 可乐 科尔B 科尔C
13 1 第415章 928
17 号 1 第415章 928
210 1 第415章 928

数据库<>小提琴