好的,这个很快就变得复杂了。我有一个系统,可以收集给定机器的硬件规格。我将专注于GPU以保持简单。一台机器可以有任意数量的GPU,并且GPU(我根据型号存储)可以存在于多台机器中。
在顶部,我有MachineSpec表,其中包含SpecID和GPUConfigID(以及其他人,但我们忽略了这些)。此GPUConfigID是GPU_Map表中GPUConfigID的外键。 GPU_Map表包含ID,GPUConfigID和GPUID列。 GPUID链接到GPU表中的GPUID,其中包含GPUID,Model,Speed等。
所以这里有一个有效的" configs"在GPU_Map表中:
我目前对该表中的所有案例都有效,但有一点需要注意。像GPUConfigIDs 1和2这样的情况会强制它们的唯一性,所以如果我尝试添加一个GPUID为1和3的新配置,它就不会让我(这很好)。不幸的是,在同一个配置中添加一个重复的GPUID(如在GPUConfigIDs 3和4中)将把它注册为一个全新的配置,尽管它是相同的。
值得注意的是,插入此表只涉及GPUID。基本上,我有一个GPUID列表,我需要看看它们是否作为GPU_Map表中的配置存在。如果他们不这样做,那么创建配置。如果是,则返回GPUConfigID。
这是我目前的存储过程:
@IDList IntList READONLY,
@ID int OUTPUT
AS
BEGIN
BEGIN TRAN gpuconfigupdate
DECLARE @Count INT
SELECT @Count = (SELECT COUNT(*)
FROM GPU_Map as Map1
LEFT OUTER JOIN @IDList as ID1
ON Map1.GPUID = ID1.Item
GROUP BY Map1.GPUConfigID
HAVING COUNT(Map1.GPUID) = (SELECT COUNT(Item) FROM @IDList)
AND COUNT(ID1.Item) = (SELECT COUNT(Item) FROM @IDList))
IF @Count IS NULL BEGIN
INSERT INTO GPU_Map (GPUConfigID, GPUID)
SELECT ((SELECT MAX(GPUConfigID) FROM GPU_Map)+1), Item FROM @IDList
END
SELECT @ID = (SELECT GPUConfigID
FROM GPU_Map as Map1
LEFT OUTER JOIN @IDList as ID1
ON Map1.GPUID = ID1.Item
GROUP BY Map1.GPUConfigID
HAVING COUNT(Map1.GPUID) = (SELECT COUNT(Item) FROM @IDList)
AND COUNT(ID1.Item) = (SELECT COUNT(Item) FROM @IDList))
COMMIT TRAN gpuconfigupdate
END
另请注意我的用户定义类型IntList:
CREATE TYPE [dbo].[IntList] AS TABLE(
[Item] [INT] NULL
);
注意:GPU_Map表之前有一个主键(GPUConfigID,GPUID),但在尝试在同一个配置中输入重复的GPUID时会抛出主键错误(如GPUConfigIDs 3和4)。这就是我创建ID列并将其设置为主键的原因,这使我了解了当前的情况。
答案 0 :(得分:0)
来自未来的人们,欢欣鼓舞!因为我已经设法找到解决这个问题的方法。
有问题的查询就是这个:
SELECT COUNT(*)
FROM GPU_Map as Map1
LEFT OUTER JOIN @IDList as ID1
ON Map1.GPUID = ID1.Item
GROUP BY Map1.GPUConfigID
HAVING COUNT(Map1.GPUID) = (SELECT COUNT(Item) FROM @IDList)
AND COUNT(ID1.Item) = (SELECT COUNT(Item) FROM @IDList)
除了@IDList包含重复值(有效)的情况之外,它按预期工作。解决方案是将最后两行更改为:
HAVING COUNT(Map1.RAMID) = COUNT(ID1.Item)
AND COUNT(DISTINCT ID1.Item) = (SELECT COUNT(DISTINCT Item) FROM @IDList))
请注意,COMMIT之前OP中存储过程的最后两行也需要以相同的方式更改。