TSql在行组上相等

时间:2011-11-09 18:59:28

标签: sql-server algorithm tsql group-by

我有一个包含有关组的信息的表。组中可以有任意数量的成员。有一个组标识符,然后是一个元素标识符。我希望能够在一个语句中确定表中是否存在给定的集合

@groupTable是数据库中已存在的数据的示例

@inputData是我想看的数据,如果它已经存在于@groupTable

declare @groupData table
(
    groupIdentifier int,
    elementIdentifier uniqueidentifier
)

insert into @groupData values
(1, 'dfce40b1-3719-4e4c-acfa-65f728677700'),
(1, '89e7e6be-cee8-40a7-8135-a54659e0d88c')

declare @inputData table
(
    tempGroupIdentifier int,
    elementIdentifier uniqueidentifier
)

insert into @inputData values
(42, 'dfce40b1-3719-4e4c-acfa-65f728677700'),
(42, '89e7e6be-cee8-40a7-8135-a54659e0d88c'),
(55, 'dfce40b1-3719-4e4c-acfa-65f728677700'),
(55, '2395a42c-94f4-4cda-a773-221b26ea5e44'),
(55, 'f22db9df-a1f4-4078-b74c-90e34376eff6')

现在我想运行一个查询来显示集合的关系,显示哪个groupIdentifier与哪个tempGroupIdentifier相关联。如果没有匹配的设置,那么我也需要知道。

desired output:
groupIdentifier, tempGroupIdentifier
1, 42
null, 55

有没有人就如何解决这个问题提出任何建议?

我可能会旋转行并将所有elementIdentifiers连接成一个巨大的字符串,然后为每个组执行相等操作,但这似乎不是一个好的解决方案。

2 个答案:

答案 0 :(得分:3)

SELECT DISTINCT
    T1.tempgroupIdentifier, T2.GroupIdentifier
FROM
    (
    SELECT
        COUNT(*) OVER (PARTITION BY tempgroupIdentifier) AS GroupCount,
        ROW_NUMBER() OVER (PARTITION BY tempgroupIdentifier ORDER BY elementIdentifier) AS GroupRN,
        tempgroupIdentifier, elementIdentifier
    FROM
        @inputData
    ) T1
    LEFT JOIN
    (
    SELECT
        COUNT(*) OVER (PARTITION BY GroupIdentifier) AS GroupCount,
        ROW_NUMBER() OVER (PARTITION BY GroupIdentifier ORDER BY elementIdentifier) AS GroupRN,
        GroupIdentifier, elementIdentifier
    FROM
        @groupData
    ) T2 ON T1.elementIdentifier = T2.elementIdentifier AND 
                      T1.GroupCount = T2.GroupCount AND 
                      T1.GroupRN = T2.GroupRN

编辑:这也将处理给定集合中的相同值

答案 1 :(得分:1)

   SELECT 
        (
        CASE WHEN matchCount = gdCount AND matchCount = idCount 
            THEN groupIdentifier 
            ELSE NULL 
        END) groupIdentifier, 
        cj.tempGroupIdentifier 
    FROM
    (
    SELECT gd.groupIdentifier, id.tempGroupIdentifier, COUNT(1) matchCount
    FROM @groupData gd 
    CROSS JOIN @inputData id
    WHERE id.elementIdentifier = gd.elementIdentifier 
    GROUP BY gd.groupIdentifier, id.tempGroupIdentifier) as cj
    CROSS APPLY (SELECT COUNT(groupIdentifier) from @groupData gdca WHERE gdca.groupIdentifier = cj.groupIdentifier) as gdc(gdCount)
    CROSS APPLY (SELECT COUNT(tempGroupIdentifier) from @inputData idca WHERE idca.tempGroupIdentifier = cj.tempGroupIdentifier) as idc(idCount)