2015-11-06 91 views
0

好吧,这个问题真的很复杂。我有一个系统收集给定机器的硬件规格。我只会专注于GPU以保持简单。一台机器可以具有任意数量的GPU,并且GPU(我基于模型存储)可以存在于多台机器中。SQL查询用于匹配输入值集合的数据的多对映表

顶部我有MachineSpec表,其中包含一个SpecID和一个GPUConfigID(和其他人,但我们忽略这些)。此GPUConfigID是GPU_Map表中GPUConfigID的外键。 GPU_Map表包含ID,GPUConfigID和GPUID列。该GPUID被链接到GPU表GPUID,其中包含GPUID,型号,速度等

因此,这里是在GPU_Map表有效“CONFIGS”的例子:

enter image description here 我有什么目前适用于该表格中的所有案例,但有一点需要注意。例如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。因此,你应该改变你的条件来检查@count为0而不是null。如果这不能解决您的问题,请发布ER图的屏幕截图,以显示这些表之间的关系。 – Adish

+0

我不知道这是真的,因为“IF @Count IS NULL”处理当前正在发生的INSERT。问题在于,当它不应该被插入时,所以上面的SELECT语句的某些内容不能捕捉到我在OP中描述的情况。 – Rein

回答

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)) 

注意的是,在OP的存储过程的最后两行提交之前还需要以同样的方式被改变。