2013-02-05 16 views
2

我想查詢一個主從式結構的預先存在的數據模型,它看起來像這樣:「主從」類型的查詢,默認「詳細」值

Master 
----- 
MasterId (PK) 
Description 


Detail 
----- 
DetailId (PK) 
MasterId (FK) 
DetailCategoryId (FK)  
Description 

有MasterId爲-1的一系列Detail記錄,它們指示每個明細類別的缺省值。因此,如果對於指定的類別,Master沒有詳細信息,則應該檢索默認值。

我已經設法爲一個給定的主記錄以幾種不同的方式做到這一點,但我迄今爲止提出的解決方案通常需要我來確定'指定'的細節,然後結合一組缺失的默認值。

我的問題是我該如何去做所有/多個主記錄? (這是一個我正在查詢報告目的的現有數據模型,我可能會做一些小的修改,但是沒有機會進行全面的重新設計,因此問題實際上是'我該如何處理這個問題'而不是不是 '?我怎麼重新模型這個')

回答

0

試試這個:

WITH CTE AS (
    SELECT M.MasterId, M.Description, D.DetailId 
    FROM Master M 
     LEFT JOIN Detail D ON M.MasterId = D.MasterId AND D.DetailCategoryId = @CatId 
) 
SELECT MasterId, Description, DetailId 
FROM CTE 
WHERE DetailId IS NOT NULL 
UNION 
SELECT CTE.MasterId, CTE.Description, D.DetailId 
FROM CTE 
    JOIN Detail D ON D.MasterId = -1 AND D.DetailCategoryId = @CatId 
WHERE CTE.DetailId IS NULL 

這裏是SQL Fiddle進行測試。

祝你好運。

+0

很確定這會給你兩個記錄 – UnhandledExcepSean

+0

編輯 - 請參閱上面的小提琴的解決方案。祝你好運。 – sgeddes

1

我認爲這會奏效。你只需要把15換成任何類別。

SELECT 
    m.MasterId,ISNULL(d.DetailId,dflt.DetailId) 
FROM Master m 
LEFT JOIN Detail d ON d.masterid=m.masterid and d.DetailCategoryId=15 
LEFT JOIN Detail dflt on dflt.masterid=-1 and d.DetailCategoryId=15 
+0

我不認爲這會起作用。用我們的兩個解決方案看這個小提琴:http://sqlfiddle.com/#!3/90672/10 - 這是我開始之前,我意識到它不會正常工作。 – sgeddes

+0

@sgeddes如果OP設置了別名權 - 第二個'left join'應該讀爲'LEFT JOIN詳細信息dflt.masterid = -1和dflt.DetailCategoryId = 15',因爲如果在'd'中沒有找到記錄, d.DetailCategoryId'將爲null,不能與'default detail'行匹配。 [SQL小提琴在這裏。](http://sqlfiddle.com/#!3/90672/21) –

+0

@NikolaMarkovinović - 是的,我明白你在說什麼。還需要添加DISTINCT:http://sqlfiddle.com/#!3/67c2f/2 – sgeddes

0

解決方案一:

DECLARE @MasterID INT; 
SET @MasterID=123; 

SELECT d.DetailID, d.DetailCategoryID, d.Description 
FROM Detail d 
WHERE [email protected]; 

IF @@ROWCOUNT=0 -- If no rows then fetch default rows 
BEGIN 
    SELECT d.DetailID, d.DetailCategoryID, d.Description 
    FROM Detail d 
    WHERE d.MasterID=-1; 
END; 

@@ROWCOUNT

解決方法二:

SELECT * 
FROM (
    SELECT *, DENSE_RANK() OVER(ORDER BY x.MasterID DESC) AS Rnk 
    FROM (
     SELECT d.MasterID, d.DetailID, d.DetailCategoryID, d.Description 
     FROM Detail d 
     WHERE [email protected] 
     UNION ALL 
     SELECT d.MasterID, d.DetailID, d.DetailCategoryID, d.Description 
     FROM Detail d 
     WHERE d.MasterID=-1 
    ) x 
) y 
WHERE y.MasterID=-1 AND y.Rnk=1 
OR y.MasterID>0; 

注:這最後的解決方案假定所有MasterID非默認值大於0(MasterID>0)。