SQL比较两个列表

时间:2015-07-31 10:53:44

标签: sql sql-server

我试图编写一个查询,根据匹配的两个列表返回一行。

我有一个包含示例数据的表

ThreadId     EntityId
1            50
1            51
2            50
2            51
2            52
3            50
3            53

我试图找到ThreadId,其中EntityIds列表与我传入的ID列表完全匹配。

示例结果

ThreadId = 1 WHEN EntityIds IN (50, 51)
ThreadId = 2 WHEN EntityIds IN (50, 51, 52)
ThreadId = 3 WHEN  EntityIds IN (50, 53)
ThreadId = NULL WHEN EntityIds IN (50, 52) -- NULL because there is no thread with just these two EntityIds

非常感谢任何帮助。

提前致谢

尼尔

2 个答案:

答案 0 :(得分:2)

您可以使用group byhaving执行此操作。如果您想要完全匹配:

select threadid
from threadentitys
group by threadid
having sum(case when entityid in (1, 2, 3) then 1 else 0 end) = 3 and
       sum(case when entityid not in (1, 2, 3) then 1 else 0 end) = 0;

第一个条件计算匹配数。 " 3"说有三个匹配 - (假设表中没有重复)意味着所有匹配。第二个说没有其他实体匹配。

答案 1 :(得分:0)

我想你想要这样的东西:

CREATE PROCEDURE [dbo].[Matcher]
    @Source AS SourceType READONLY
AS
    BEGIN

        DECLARE @RetVal INT;

        DECLARE @MatchString VARCHAR(MAX);

        DECLARE @TargetSet TABLE
            (
              threadid INT ,
              entities VARCHAR(MAX) ,
              processed BIT DEFAULT 0
            );

        DECLARE @newcsv VARCHAR(MAX);

        DECLARE @currentthread INT;

        INSERT  INTO @TargetSet
                ( threadid
                )
                SELECT DISTINCT
                        threadid
                FROM    TheData;

        -- Flatten the source string

        SET @MatchString = ( SELECT SUBSTRING(( SELECT  ','
                                                        + CAST(s.EntityId AS VARCHAR)
                                                FROM    @Source s
                                                ORDER BY s.EntityId
                                              FOR
                                                XML PATH('')
                                              ), 2, 200000) AS CSV
                           );       

        -- Flatten the target data

        WHILE ( SELECT  COUNT(*)
                FROM    @TargetSet
                WHERE   processed = 0
              ) > 0
            BEGIN

                SET @currentthread = ( SELECT TOP 1
                                                threadid
                                       FROM     @TargetSet
                                       WHERE    processed = 0
                                     );

                SET @newcsv = ( SELECT  SUBSTRING(( SELECT  ','
                                                            + CAST(EntityId AS VARCHAR)
                                                    FROM    TheData
                                                    WHERE   ThreadId = @currentthread
                                                    ORDER BY EntityId
                                                  FOR
                                                    XML PATH('')
                                                  ), 2, 200000) AS CSV
                              );

                UPDATE  @TargetSet
                SET     entities = @newcsv ,
                        processed = 1
                WHERE   threadid = @currentthread;

            END;

        -- Perform the match

        SET @RetVal = ( SELECT  threadid
                        FROM    @TargetSet
                        WHERE   entities = @MatchString
                      );            

        SELECT  @RetVal;

    END;

我已经提起了表格 - >来自here的CSV代码,但是如果这不是你的想象,还有很多其他的例子在网上蠢蠢欲动。

相关问题