SQL 与按列值分组的交集

问题描述 投票:0回答:2

我想在基于另一列的一列的值之间相交。我的意思是,如果我在 Id 列中有三个不同的值,我希望 LineGroupBy 列的值被假定为一组(Id=1)并与其他组(Id=5 或 8)相交 这是表格:

LineGroupBy    Id

ItemTypeId      8
ItemId          1
BankAccountId   5
ItemTypeId      1
VATId           1
InOut           5
FundTypeId      5
CurrencyId      5
VATPer          1
ItemId          8

查询结果应该为NULL。如您所见,Id=1 的 LineGroupBy 值是 (ItemId,ItemTypeId,VATId,VATPer), Id=5 是 (InOut,FundTypeId,CurrencyId) 并且 Id=8 是 (ItemTypeId,ItemId).

所以 Id=1 和 Id=8 有一个 (ItemTypeId,ItemId) 的交集,但总的来说所有 Id 之间没有交集。

我试过这个,但它是静态的(地址确切 ID),我想要一个不解决 ID 的查询。

SELECT *
FROM #temp T
WHERE T.Id=1
INTERSECT
SELECT *
FROM #temp T
WHERE T.Id=5
INTERSECT
SELECT *
FROM #temp T
WHERE T.Id=8
sql group-by intersect
2个回答
0
投票

我发现这段代码说明了重叠,但这段代码没有说明所有组的交集是什么。

WITH temp(Id) AS
( 
SELECT DISTINCT Id
FROM #temp
), 
couples (Id1, Id2, LineGroupBy) AS 
( 
SELECT a.Id, b.Id, a.LineGroupBy
    FROM #temp a 
    JOIN #temp b ON a.Id < b.Id AND a.LineGroupBy = b.LineGroupBy 
    GROUP BY a.Id, b.Id, a.LineGroupBy
)
SELECT a.Id AS Id1, 
       b.Id AS Id2, 
       c.LineGroupBy AS common_items
FROM temp a
INNER JOIN temp b ON a.Id <= b.Id
LEFT JOIN couples c ON  a.Id = c.Id1 AND b.Id = c.Id2

查找所有 ID 的路径的额外代码可以工作。


0
投票

这使用字符串连接来确定哪些 id 共享 LineGroupBy 值。它还确保 ID 不重复且有序。

SELECT Groups.LineGroupBy, STUFF((
  SELECT ',' + CAST(t2.id AS VARCHAR(20))
  FROM (select distinct LineGroupBy, Id from temp) t2
  WHERE Groups.LineGroupBy = t2.LineGroupBy
  ORDER BY t2.id
  FOR XML PATH('')
), 1, 1, '') AS IdList
FROM (SELECT DISTINCT LineGroupBy FROM temp) AS Groups
线组依据 IdList
BankAccountId 1,5,6,8 << test data: this is common to all ids
货币编号 5,6
FundTypeId 5,6
进出 5,6
ItemId 1,6,8
ItemTypeId 1,6,8
VATId 1,6
VATPer 1,6

然后我们将该结果(上图)与不同的 id 列表进行比较,以便 where 子句也是自动化的:

WITH CTE as (
    SELECT Groups.LineGroupBy, STUFF(
        (
          SELECT ',' + CAST(t2.id AS VARCHAR(20))
          FROM (SELECT DISTINCT LineGroupBy, Id FROM temp) t2
          WHERE Groups.LineGroupBy = t2.LineGroupBy
          ORDER BY t2.id
          FOR XML PATH('')
        ), 1, 1, '') AS IdList
    FROM (SELECT DISTINCT LineGroupBy FROM temp) AS Groups
  )
SELECT LineGroupBy, IdList
FROM CTE
WHERE IdList = (
    SELECT STUFF((
        SELECT ',' + CAST(id AS VARCHAR(20))
        FROM (SELECT DISTINCT Id FROM temp) t
        ORDER BY id
    FOR XML PATH('')
    ), 1, 1, '') 
  )
线组依据 IdList
BankAccountId 1,5,6,8

小提琴


原帖:

我不确定您真正要求的是什么,因为您没有指定任何实际输出,但认为这可能会有所帮助:

SELECT Groups.LineGroupBy, STUFF((
    SELECT ',' + CAST(t2.id AS VARCHAR(20))
    FROM temp t2
    WHERE Groups.LineGroupBy = t2.LineGroupBy
    FOR XML PATH('')
), 1, 1, '') AS IdList
FROM (SELECT DISTINCT LineGroupBy FROM temp) AS Groups

来自给定的样本数据:

线组依据 IdList
BankAccountId 5
货币编号 5
FundTypeId 5
进出 5
ItemId 1,8
ItemTypeId 8,1
VATId 1
VATPer 1
INSERT INTO temp (LineGroupBy, Id)
VALUES
    ('ItemTypeId',6),
    ('ItemId',6),
    ('BankAccountId',6),
    ('ItemTypeId',6),
    ('VATId',6),
    ('InOut',6),
    ('FundTypeId',6),
    ('CurrencyId',6),
    ('VATPer',6)
  ;

添加一些额外数据后

线组依据 IdList
BankAccountId 5,6
货币编号 5,6
FundTypeId 5,6
进出 5,6
ItemId 1,8,6
ItemTypeId 8,1,6,6
VATId 1,6
VATPer 1,6

小提琴

© www.soinside.com 2019 - 2024. All rights reserved.