2015-11-06 89 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的存儲過程的最後兩行提交之前還需要以同樣的方式被改變。