2016-11-17 16 views
3

Iは、次のエラーを取得:このコードでT-SQL集約関数サブクエリ

Cannot perform an aggregate function on an expression containing an aggregate or a subquery. 

SELECT 
    loc.Location 
    ,COUNT(CASE 
     WHEN hr.SAC in (SELECT [SAC] FROM dbo.[Titles] WHERE [title] = 'XYZ') 
      THEN 1 
      ELSE NULL 
     END) AS XYZ_Trainee_Count 
    ,COUNT(CASE 
     WHEN hr.SAC in (SELECT [SAC] FROM dbo.[Titles] WHERE [title] = 'ABC') 
      THEN 1 
      ELSE NULL 
     END) AS ABC_Trainee_Count 

FROM 
    dbo.n_HRODS hr INNER JOIN dbo.Locations loc 
     ON loc.LocationID = hr.LocationID 
    INNER JOIN dbo.EmpData dat 
     ON dat.EmpID = hr.EmpID 

WHERE dat.Trainee = 1 

GROUP BY loc.Location 

DBOを[タイトル]は、二つの他のテーブルからの2つの列を組み合わせた図です。私は基本的に私の前に、プログラマはこのようなものでしたので、それをこのようにやっている:明らか

,COUNT(CASE 
    WHEN SAC in (lists about 30 items) 
     THEN 1 
     ELSE NULL 
    END) 

を、私はそのcase文には30個の項目を一覧表示したくない...とするとき、それらのアイテムが何のために変更します理由は3年後、誰がこのコードに戻ってそれらのアイテムを更新するのを覚えていますか?誰も...

ご協力いただきありがとうございます。

答えて

2

あなたはそのtitleテーブルに余分なLEFT OUTER JOINsのカップルでこれを行うことができます。実際のクエリは大きな悪夢とあるので、あなたのSELECT文でこれらのサブクエリには本当に結婚している場合は、代わりに

SELECT 
    loc.Location 
    ,COUNT(CASE WHEN titles1.[SAC] IS NOT NULL THEN 1 ELSE NULL END) AS XYZ_Trainee_Count 
    ,COUNT(CASE WHEN titles2.[SAC] IS NOT NULL THEN 1 ELSE NULL END) AS ABC_Trainee_Count 

FROM 
    dbo.n_HRODS hr INNER JOIN dbo.Locations loc 
     ON loc.LocationID = hr.LocationID 
    INNER JOIN dbo.EmpData dat 
     ON dat.EmpID = hr.EmpID 
    LEFT OUTER JOIN dbo.[Titles] titles1 
     ON titles1.[title]='XYZ' AND 
      hr.SAC = titles1.[SAC] 
    LEFT OUTER JOIN dbo.[Titles] titles2 
     ON titles2.[title]='ABC' AND 
      hr.sac = titles2.[SAC]  
WHERE dat.Trainee = 1  
GROUP BY loc.Location 

あなたがかすかせるのに十分である合流し、その後、あなたはこのクエリから集計を削除し、集約する前に、サブクエリの中にそれをすべてを突き出すことができmonkeying考える:

SELECT location, count(XYZ_Trainee) AS XYZ_Trainee_Count, count(ABC_Trainee) as ABC_Trainee 
FROM 
(
    SELECT 
     loc.Location 
     ,CASE 
      WHEN hr.SAC in (SELECT [SAC] FROM dbo.[Titles] WHERE [title] = 'XYZ') 
       THEN 1 
       ELSE NULL 
      END AS XYZ_Trainee 
     ,CASE 
      WHEN hr.SAC in (SELECT [SAC] FROM dbo.[Titles] WHERE [title] = 'ABC') 
       THEN 1 
       ELSE NULL 
      END AS ABC_Trainee 

    FROM 
     dbo.n_HRODS hr INNER JOIN dbo.Locations loc 
      ON loc.LocationID = hr.LocationID 
     INNER JOIN dbo.EmpData dat 
      ON dat.EmpID = hr.EmpID 

    WHERE dat.Trainee = 1 
) sub 
GROUP BY location 

私は最初を目指しますこれは、管理しやすく、おそらくRDBMSからより良い実行パスを取得し、結果としてより速く実行できるためです。しかし...それはちょうど推測です。

+0

ありがとうございました! – blacksaibot

2

JNevillと非常によく似ています。しかし、あなたが一度タイトルに参加すると、あなたが望む任意の数のタイトルをチェックして数えることができます。

SELECT 
    loc.Location 
    ,COUNT(CASE WHEN t.[title] = 'XYZ' THEN 1 END) AS XYZ_Trainee_Count 
    ,COUNT(CASE WHEN t.[title] = 'ABC' THEN 1 END) AS ABC_Trainee_Count 

FROM 
    dbo.[n_HRODS] hr 
INNER JOIN dbo.[Locations] loc 
     ON loc.LocationID = hr.LocationID 
INNER JOIN dbo.[EmpData] dat 
     ON dat.EmpID = hr.EmpID 
INNER JOIN dbo.[Titles] t 
     ON hr.SAC = t.[SAC]  
WHERE dat.Trainee = 1 

GROUP BY loc.Location  
+0

ああ、面白い。情報をありがとう! – blacksaibot

関連する問題