2013-04-14 172 views
3

我目前正在工作的查詢返回所需的結果,但問題是我必須爲每個要添加的額外列創建一個具有不同TaskCounters的額外連接(這當然不是理性決策)。SQL Server加入

該查詢應該在SQLServer以及Access DB上運行,因此我不需要任何特殊功能(如Pivot,CTE等),這些功能在訪問中不受支持。我需要修改該查詢,以便儘可能減少聯接的數量。

tblConsultations是根據訪問類型(即,如果我們有4次訪問,我們有4次諮詢的條目)記錄特定兒童的條目的主表。結果列應顯示這4次訪問的值,如果沒有訪問值,則顯示NULL。

我想無需額外從中我必須添加每增加列同表連接

查詢如下:

SELECT Cast(SUBSTRING(tc2.ChildCounter, 7, LEN(tc2.ChildCounter)) AS NUMERIC) AS pkChildID 
,tc2.VisitType 
,tblQuitOffered.Result AS KWA_QuitOffered 
,tblQuitReferral.Result As KWA_QuitReferral 
FROM tblConsultations tc2 
INNER JOIN tblChild tc ON tc2.ChildCounter = tc.ChildCounter 
LEFT JOIN tblDelivery td ON td.ChildCounter = tc.ChildCounter 
LEFT JOIN (
SELECT ttr.ResultCounter 
    ,ttr.ChildCounter 
    ,tkt.VisitType 
    ,ttr.Result 
    ,ttr.TaskCounter 
FROM tblTaskResults ttr 
INNER JOIN tlkpKeyTasks tkt ON tkt.TaskCounter = ttr.TaskCounter 
    AND tkt.TaskCounter IN (
     '001410' 
     ,'001463' 
     ,'001431' 
     ) 

) AS tblQuitOffered ON tc2.VisitType = tblQuitOffered.VisitType 
AND tblQuitOffered.ChildCounter = tc2.ChildCounter 
LEFT JOIN (
SELECT ttr.ChildCounter 
    ,tkt.VisitType 
    ,ttr.Result 
FROM tblTaskResults ttr 
INNER JOIN tlkpKeyTasks tkt ON tkt.TaskCounter = ttr.TaskCounter 
    AND tkt.TaskCounter IN (
     '001411' 
     ,'001464' 
     ,'001432' 
     ) 
) AS tblQuitReferral ON tc2.VisitType = tblQuitReferral.VisitType 
AND tblQuitReferral.ChildCounter = tc2.ChildCounter 
WHERE tc2.VisitType in (1, 2, 3, 4) 
AND tc2.ConsDate BETWEEN '20130127' and '20130228' 
ORDER BY tc2.ChildCounter,tc2.VisitType 

結果如下: :

pkChildID VisitType  KWA_QuitOffered KWA_QuitReferral 
2224  1    No    No 
2224  3    NULL    NULL 
2224  4    NULL    NULL 
2225  1    No    Yes 
2225  2    Yes    Yes 
2225  3    Yes    Yes 
2225  4    NULL    NULL 
+2

我不認爲你會找到一個令人滿意的答案,可以同時使用SQL Server和MS Access。正如bluefeet提到的那樣,SQL語法本身是不同的。您可能需要針對每個環境提供不同的解 – BellevueBob

+0

@BellevueBob我不同意,看起來像AMS所需要的只是GROUP BY子句。但是對我來說,一個謎就是使用TaskCounter來確定QuitOffered和QuitReferral。 –

+0

@BellevueBob - 我相信我找到了答案:D – Hogan

回答

1

如果我理解正確,您可以包含所有需要的TaskCounter值英格爾派生表,然後使用CASE語句來給你列值:

SELECT Cast(SUBSTRING(tc2.ChildCounter, 7, LEN(tc2.ChildCounter)) 
      AS NUMERIC) AS pkChildID 
     ,tc2.VisitType 

     ,MAX(CASE WHEN tktResults.TaskCounter IN (
       '001410' 
       ,'001463' 
       ,'001431' 
       ) THEN tktResults.Result END 
     ) AS KWA_QuitOffered 

     ,MAX(CASE WHEN tktResults.TaskCounter IN (
       '001411' 
       ,'001464' 
       ,'001432' 
       ) THEN tktResults.Result END 
     ) AS KWA_QuitReferral 

FROM tblConsultations tc2 
INNER JOIN tblChild tc 
    ON tc2.ChildCounter = tc.ChildCounter 
LEFT JOIN tblDelivery td 
    ON td.ChildCounter = tc.ChildCounter 

LEFT JOIN (
    SELECT ttr.ResultCounter 
     ,ttr.ChildCounter 
     ,tkt.VisitType 
     ,ttr.Result 
     ,ttr.TaskCounter 
    FROM tblTaskResults ttr 
    INNER JOIN tlkpKeyTasks tkt 
    ON tkt.TaskCounter = ttr.TaskCounter 
     AND tkt.TaskCounter IN (
      '001410' 
      ,'001463' 
      ,'001431' 
      ,'001411' 
      ,'001464' 
      ,'001432' 
      ) 
    ) AS tktResults 
ON  tktResults.VisitType = tc2.VisitType 
    AND tktResults.ChildCounter = tc2.ChildCounter 

WHERE tc2.VisitType in (1, 2, 3, 4) 
    AND tc2.ConsDate BETWEEN '20130127' and '20130228' 
GROUP BY 1, 2 
ORDER BY tc2.ChildCounter,tc2.VisitType 

如果事實上,你並不真正需要做的是一個派生表(LEFT JOIN (...)部分),但我假設你是出於性能原因這樣做。當您根據TaskCounter的不同值添加列時,只需將它們添加到連接條件即可。

編輯:修訂使用GROUP BY條款與MAX功能由pkChildIDVisitType返回唯一的行。

我在GROUP BY子句中使用「有序列表」樣式;如果不支持,你可能需要像這樣指定它:

GROUP BY Cast(SUBSTRING(tc2.ChildCounter, 7, LEN(tc2.ChildCounter)) AS NUMERIC) 
     ,tc2.VisitType 

我也注意到你正在對一個不屬於SELECT子句的列進行排序。我不確定爲什麼,但保持不變。

+0

Ms Access中沒有'CASE'。 – Taryn

+0

@bluefeet顯然不是;但我認爲可以使用VBA。我錯過了有關包含MS Access的便攜式解決方案的部分。不要使用Access來進行「真正的」工作。 – BellevueBob

+0

困難的是SQL服務器和ms訪問之間的可移植性,但不幸的是它們不具有相同的語法,包括函數和JOIN。 MS Access需要多個表連接的括號。 – Taryn

1

我發佈了一些答案,有些像BellevueBob發佈的。

我想在SQL‘

+0

網絡搜索也向我透露了'SWITCH'函數,它也可能適用於Access,但很可惜,我不認爲這兩種函數都可以在SQL Server中工作。 – BellevueBob

+0

取決於可能不支持哪種版本的SQL Server'IIF'。它在SQL Server 2012中可用。 – Taryn

+0

ooo我看到了..你想要一些可以同時運行sql和Ms Access的東西...你是對的BellevueBob ... – Fuad

0

的時候經常做一個新表解決了一個問題,你可以使用嵌套IIF()的,而不是’情況。讓我們稱之爲coderesolve。

它看起來像這樣:

Code QuitOffered QuitReferral 
001410 1    Null 
001462 1    Null 
001431 1    Null 
001411 Null   1 
001464 Null   1 
001432 Null   1 

您可以添加更多的列每一個「新」加入你想做的事情。

然後你的代碼看起來像這樣

SELECT 
    Cast(SUBSTRING(tc2.ChildCounter, 7, LEN(tc2.ChildCounter)) AS NUMERIC) 
    AS pkChildID 
    ,tc2.VisitType 
    ,ttr.Result AS KWA_QuitOffered 
    ,ttr.Result As KWA_QuitReferral 
FROM tblConsultations tc2 
INNER JOIN tblChild tc ON tc2.ChildCounter = tc.ChildCounter 
LEFT JOIN tblDelivery td ON td.ChildCounter = tc.ChildCounter 
JOIN tblTaskResults ttr on tc2.VisitType = ttr.VisitType 
JOIN tlkpKeyTasks tkt ON tkt.TaskCounter = ttr.TaskCounter 
JOIN coderesolve cr on cr.code = tkt.TaskCounter 
    AND COALESCE(cr.QuitOffered,cr.QuitReferral,0) = 1 
WHERE tc2.VisitType in (1, 2, 3, 4) 
AND tc2.ConsDate BETWEEN '20130127' and '20130228' 
ORDER BY tc2.ChildCounter,tc2.VisitType 

這應該對訪問工作。但訪問很有趣,所以沒有承諾。

另一個說明,我假設你的代碼是相互排斥的(它只給你coderesolve連接上的一行結果),如果不是這種情況,你可能不得不把它分解成一個子查詢並做一個分組或獨特 - 取決於你的模型。