我试图编写一个查询,根据匹配的两个列表返回一行。
我有一个包含示例数据的表
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
非常感谢任何帮助。
提前致谢
尼尔
答案 0 :(得分:2)
您可以使用group by
和having
执行此操作。如果您想要完全匹配:
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代码,但是如果这不是你的想象,还有很多其他的例子在网上蠢蠢欲动。