我当前正在处理的查询返回了所需的结果,但问题是我必须为要添加的每个额外的列创建一个具有不同TaskCounters的附加联接(这当然不是一个合理的决定)。

该查询应该在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

最佳答案

如果我理解正确,则可以在单个派生表中包含所有想要的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子句的列进行排序。我不知道为什么,但保持不变。

关于sql - SQL Server连接,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15998132/

10-10 18:05