2016-09-30 4 views
1

어떻게 내가 다시 쓰기는 다음과 같은 오류가 실행되지 않도록이 쿼리를 ". 집계 또는 하위 쿼리가 포함 된 식에서는 집계 함수를 수행 할 수 없습니다"SUM CASE를 사용하는 경우 SELECT

SELECT 
    employees.loc_id 
    ,SUM(CASE 
      WHEN 
       pos IN (SELECT DISTINCT pos FROM lookup WHERE lbl='Staff') 
      AND 
       loc IN (SELECT DISTINCT loc FROM lookup WHERE lbl='Staff') 
      THEN 1 
      ELSE 0 
     END) AS 'Staff Site 1' 
    ,SUM(CASE 
      WHEN 
       pos IN (SELECT DISTINCT pos FROM table WHERE lbl='Staff') 
      AND 
       loc IN (SELECT DISTINCT loc FROM table WHERE lbl='Staff') 
      THEN 1 
      ELSE 0 
     END) AS 'Staff Site 2' 

FROM table GROUP BY table.key_id ORDER BY key_id 

그래서 분명히 내가 SUMSELECT 문을 넣을 수없는 이유는 무엇입니까? 위의 코드에 설명 된 사례에 대해서만 합산 할 수 있도록하려면 어떻게해야합니까?

pos은 위치 유형을 결정합니다. loc은 어떤 사이트 (위치)에서 결정합니다. 룩업 테이블은 다음과 같이 구성된다 :

pos | loc | lbl 
123 | XYZ | Staff Site 1 
456 | XYZ | Staff Site 1 
987 | XYZ | Supervisor Site 1 
123 | ABC | Staff Site 2 
123 | JKL | Staff Site 3 
123 | OPQ | Staff Site 4 
456 | OPQ | Staff Site 4 
345 | OPQ | Staff Site 4 

이 룩업 테이블은 단순히 특정 위치의 위치와 연관된 레이블을 결정한다.

직원 테이블이 있고 각 직원에게 pos #가 지정됩니다.

그래서 나는 직원 테이블에서 모든 loc_id (위치 ID)를 선택 내 쿼리를 원하고, 각 loc_id, 나는이 pos=123loc_id=XYZ 30 명의 직원이 있다면

그래서 조회 테이블에서 각각의 항목을 요약 및 loc_id=XYZ 20 명 직원 pos=456으로, 출력은 사전에

loc_id | Staff Site 1 
XYZ | 50 

감사합니다 것, 나는 ...이 너무 복잡하지 않았다 희망

답변

4

집계 함수 내에서 SELECT를 수행 할 수있는 기술을 습득하지 않고도. 뒤로 물러서서 쿼리를 모두 다시 생각해 봅시다. 조회 테이블을 집계하여 해결하려고 시도하지만 집계는 실제로 조회 테이블의 조인을 사용하여 Employee 테이블에 있습니다.

조건부 집계를 수행하여 결과를 PIVOT하려고 시도하는 것 같습니다.

SELECT 
    l.loc 
    ,COUNT(DISTINCT e.Id) as EmployeesAtStaffSite1 
FROM 
    Lookup l 
    INNER JOIN Employees e 
    ON e.loc = l.loc 
    AND e.pos = l.pos 
WHERE 
    l.lbl = 'Staff Site 1' 
GROUP BY 
    l.loc 

은 또한 변경할 경우 INNER이 어떤 위치에 대한 0 수를 얻을 수 있습니다 당신을 가입 왼쪽으로 가입 참고 : 그러나 어느 경우에 당신은 다음 작업을 수행 할 경우 사용자가 지정하는 결과를 얻을 수 있습니다 다음과 같은 경우 직원 사이트 1 직원이 배정되지 않았습니다.

+2

이것이 OP가 반환하려고하는 결과를 반환하는 것으로 의심되지만 정확한 사양을 결정하는 것은 어렵습니다. +10 "키보드에서 손가락을 떼어 내고, 천천히 뒤로 물러나서, 우리가 성취하고자하는 것에 대해 생각하고 설명하는 방법을 ..." – spencer7593

+0

화려한 매트. 고맙습니다. – blacksaibot

0

이 작업을 수행하는 한 가지 방법은 실제로 집계를 외부 쿼리에 넣고 조건부 항목 (예 : 이 같은 서브 쿼리) :

select key_id, sum(staff_site_1) as staff_site_1, , sum(staff_site_2) as staff_site_2 
from (
    SELECT 
    employees.key_id 
    ,CASE 
     WHEN 
      pos IN (SELECT DISTINCT pos FROM lookup WHERE lbl='Staff') 
     AND 
      loc IN (SELECT DISTINCT loc FROM lookup WHERE lbl='Staff') 
     THEN 1 
     ELSE 0 
    END AS staff_site_1 
    ,CASE 
     WHEN 
      pos IN (SELECT DISTINCT pos FROM lookup WHERE lbl='Staff') 
     AND 
      loc IN (SELECT DISTINCT loc FROM lookup WHERE lbl='Staff') 
     THEN 1 
     ELSE 0 
    END AS staff_site_2 
    FROM table 
) x 
GROUP BY key_id 
ORDER BY key_id 
0
; with _CTE as (
SELECT 
    employees.loc_id 
    ,CASE 
      WHEN 
       pos IN (SELECT DISTINCT pos FROM lookup WHERE lbl='Staff') 
      AND 
       loc IN (SELECT DISTINCT loc FROM lookup WHERE lbl='Staff') 
      THEN 1 
      ELSE 0 
     END AS StaffSite1 
    ,CASE 
      WHEN 
       pos IN (SELECT DISTINCT pos FROM table WHERE lbl='Staff') 
      AND 
       loc IN (SELECT DISTINCT loc FROM table WHERE lbl='Staff') 
      THEN 1 
      ELSE 0 
     END AS StaffSite2 

FROM table 
) 
SELECT 
    loc_id 
    ,SUM(StaffSite1) AS 'Staff Site 1' 
    ,SUM(StaffSite2) AS 'Staff Site 2' 

FROM _CTE GROUP BY loc_id ORDER BY loc_id 

설명 : _CTE 데이터에 CASE 조건을 적용 여기서 임시 결과 집합이다. 그런 다음이 결과 집합에 대해 집계 함수를 실행하고 있습니다.

+0

cte는 임시 테이블이 아니며 표현식입니다. 이것을 최종 선택 명령문에 추가 코드없이 모두 파생 테이블을 정의하는 방법으로 생각하십시오. 단일 SELECT의 실행 스코어 내에서 정의 된 임시 결과 세트 ... 정의 할 때 실행되지 않으므로이를 사용하는 최종 명령문과 관련하여 실행됩니다. https://technet.microsoft.com/en-us/library/ms190766(v=sql.105).aspx – Matt

+1

감사합니다. Matt. 실수를 바로 잡기 위해 내 대답을 수정했습니다. – Sparrow

+0

도움에 감사드립니다. – blacksaibot

1

외부 쿼리는 테이블 이름 table을 참조하지만 SELECT 목록의 열은 employees.으로 규정됩니다. 쿼리는 GROUP BY table.key_id을 수행하지만 SELECT 목록에 반환 된 열은 loc_id 열로 반환됩니다.두 하위 쿼리 모두 이라는 첫 번째 세트의 찾는 테이블 인 'Staff'와 일치하는 lbl을 찾습니다. 해당 조건이 true로 평가되는 lookup 테이블에 예제 행이 표시되지 않습니다. 두 번째 집합에서 하위 쿼리는 다른 테이블 (불행하게도 명명 된) table을 참조합니다.

실제로 어떤 쿼리를 사용하여 달성하려고했는지 알기가 어렵습니다.

혼란스럽게도 질문의 마지막 부분은 직원 테이블에서 loc_id의 고유 값인 두 개의 열이있는 결과 집합을 사용하는 것이 좋습니다. 그리고 일부 기준 집합을 만족하는 행 수를 포함하는 일종의 집계 열 ...

loc_id Staff Site 1 
------ ------------ 
XYZ    50 

몇 단계를 백업 해 봅니다.

employee 테이블의 모든 행을보고 싶은데 테이블의 3 개 또는 4 개의 열에 만 관심이있는 것 같습니다. 이것은 분석하려는 행과 열의 집합입니다. (그것은 당신이 table 테이블에서 lbl라는 이름의 열을 참조 할 필요 여부를 명확하지 않다. table 대신 lookup의 참조 서브 쿼리의 한 세트는 그 사건처럼 보이게.

그래서, 행 세트로 시작 당신은 쿼리가에서

SELECT e.loc_id 
     , e.pos 
     , e.loc 
    FROM employee e 

, 당신은 loc_id의 고유 한 값을 얻으려면 ...보고 싶다. 그리고 당신은 GROUP BY 절을 추가하여 그것을 달성 할 것입니다.

우리는 쉽게 할 수 모든 ro의 "카운트"를 얻는다. 각 loc_id과 관련된 직원의 총계는 COUNT(*)입니다. 그러나 특정 조건을 충족하는 직원 만 계산하는 데 관심이 있습니다 ... 조건부 집계.

(loc_id,pos)의 조합이 찾아보기 테이블에서 UNIQUE 인 경우. (예제 데이터는 그 것처럼 보이지만 제한된 예제 데이터에서 반례가 없다는 것을 확인할 수는 없습니다 ...

그게 유일한 경우 해당 테이블에 대해 JOIN 연산을 수행 할 수 있습니다 각 직원의 (loc_id,pos)과 연결된 lbl을 "조회"할 수 있습니다.

SELECT e.loc_id 
     , e.pos 
     , e.loc 
     , l.lbl 
    FROM employee e 
    LEFT 
    JOIN lookup l 
    ON l.loc_id = e.loc_id 
    AND l.pos = e.pos 

내가 Staff Site 1lbllookup의 행과 관련이 주어진 위치에서 직원의 수를 원한다면, 내가 쓰는 경향이 ... 같은

SELECT e.loc_id 
     , SUM(CASE WHEN l.lbl = 'Staff Site 1' THEN 1 ELSE 0 END) AS [Staff Site 1] 
    FROM employee e 
    LEFT 
    JOIN lookup l 
    ON l.loc_id = e.loc_id 
    AND l.pos = e.pos 
    GROUP BY e.loc_id 
    ORDER BY e.loc_id 

내가의 카운트를 들어, 두 번째 열을 원하는 경우 '직원 사이트 2'

SELECT e.loc_id 
     , SUM(CASE WHEN l.lbl = 'Staff Site 1' THEN 1 ELSE 0 END) AS [Staff Site 1] 
     , SUM(CASE WHEN l.lbl = 'Staff Site 2' THEN 1 ELSE 0 END) AS [Staff Site 2] 
    FROM employee e 
    LEFT 
    JOIN lookup l 
    ON l.loc_id = e.loc_id 
    AND l.pos = e.pos 
    GROUP BY e.loc_id 
    ORDER BY e.loc_id 

내가 특별히 필요하지 않은 경우에 "피벗 "그 결과, 에 각 employee에 대해 lbl의 모든 값에 대해 별도의 행을 반환하는 쿼리를 훨씬 간단하게 실행할 수있었습니다. 난 아무데도 당신이 employees.loc_id와 gouping되어 표시되지 않습니다

SELECT e.loc_id AS loc_id 
     , e.lbl  AS lbl 
     , SUM(1) AS cnt 
    FROM employee e 
    LEFT 
    JOIN lookup l 
    ON l.loc_id = e.loc_id 
    AND l.pos = e.pos 
    GROUP BY e.loc_id 
    ORDER BY e.loc_id 
+0

철저한 설명과 고장을 가져 주셔서 감사합니다. – blacksaibot

0

아직은 선택입니다.대신 당신은 오직 GROUP BY table.key_id ORDER BY key_id

관련 문제