northwind 샘플 DB에서 공부중입니다.
orders와 employees를 연결해서 1996년 7월의 employeeID별로 요일의 freight 합계를 구하는 것입니다.
해당 월에 한건의 freight가 없었던 것도 리스트에 출력하하고, 맨 끝줄에 총 freight를 구해야합니다.
계속 헤매고 있네요. 안풀리는 부분의 핵심은 employeeID = 7의 출력입니다. 정답 코드와 같이.
제가 작성한 코드입니다.
SELECT
CASE
WHEN(E.employeeID BETWEEN 1 AND 9) THEN 'DATA'
ELSE 'TTL'
END AS [DataType],
E.employeeID, (SELECT title FROM employees AS T WHERE T.employeeID = E.employeeID) AS [Title],
isnull(sum(CASE WHEN(datepart(dw, O.orderDate) = 2) THEN O.freight END),0) AS [MonFreight],
isnull(sum(CASE WHEN(datepart(dw, O.orderDate) = 3) THEN O.freight END),0) AS [TueFreight],
isnull(sum(CASE WHEN(datepart(dw, O.orderDate) = 4) THEN O.freight END),0) AS [WedFreight],
isnull(sum(CASE WHEN(datepart(dw, O.orderDate) = 5) THEN O.freight END),0) AS [ThrFreight],
isnull(sum(CASE WHEN(datepart(dw, O.orderDate) = 6) THEN O.freight END),0) AS [FriFreight]
FROM employees AS E
LEFT OUTER JOIN orders AS O
ON O.EmployeeID = E.EmployeeID
WHERE year(O.orderDate) = 1996 AND month(O.orderDate) = 7
GROUP BY E.employeeID WITH ROLLUP
GO
제 쿼리를 실행한 결과입니다.
DataType | EmployeeID | Title | MonFreight | TueFreight | WedFreight | ThrFreight | FriFreight |
DATA | 1 | Sales Representative | 0 | 0 | 140.51 | 0 | 0 |
DATA | 2 | Vice President, Sales | 0 | 0 | 0 | 55.28 | 0 |
DATA | 3 | Sales Representative | 55.31 | 0 | 58.17 | 0 | 25.73 |
DATA | 4 | Sales Representative | 274.41 | 133.21 | 0 | 3.25 | 58.14 |
DATA | 5 | Sales Manager | 0 | 0 | 4.56 | 55.36 | 0 |
DATA | 6 | Sales Representative | 0 | 0 | 3.67 | 0 | 11.61 |
DATA | 8 | Inside Sales Coordinator | 48.29 | 66.29 | 0 | 0 | 0 |
DATA | 9 | Sales Representative | 0 | 146.06 | 0 | 0 | 148.33 |
TTL | NULL | NULL | 378.01 | 345.56 | 206.91 | 113.89 | 243.81 |
출력결과는 아래와 같이 나와야 합니다.
DataType EmployeeID Title MonFreight TueFreight WedFreight ThrFreight FriFreight
-------- ----------- ------------------------------ --------------------- --------------------- --------------------- --------------------- ---------------------
DATA 1 Sales Representative 0.0000 0.0000 140.5100 0.0000 0.0000
DATA 2 Vice President, Sales 0.0000 0.0000 0.0000 55.2800 0.0000
DATA 3 Sales Representative 55.3100 0.0000 58.1700 0.0000 25.7300
DATA 4 Sales Representative 274.4100 133.2100 0.0000 3.2500 58.1400
DATA 5 Sales Manager 0.0000 0.0000 4.5600 55.3600 0.0000
DATA 6 Sales Representative 0.0000 0.0000 3.6700 0.0000 11.6100
DATA 8 Inside Sales Coordinator 48.2900 66.2900 0.0000 0.0000 0.0000
DATA 9 Sales Representative 0.0000 146.0600 0.0000 0.0000 148.3300
DATA 7 Sales Representative NULL NULL NULL NULL NULL
TTL NULL NULL 378.0100 345.5600 206.9100 113.8900 243.8100
Comment 9
-
이리
2013.04.05 12:26
-
KJS
2013.04.05 13:09
해당 데이터가 검색되지 않는 이유는
WHERE year(O.orderDate) = 1996 AND month(O.orderDate) = 7
조건이 WHERE 절에 있기 때문인것 같습니다.
해당 조건을 아래와 같이 JOIN 조건으로 사용하면 원하시는 데이터가 검색 될것 같습니다.
ON O.EmployeeID = E.EmployeeID AND ON O.EmployeeID = E.EmployeeID
물론 WHERE 있는 해당 조건은 삭제 해야 합니다.
감사합니다.
-
이리
2013.04.05 13:13
저도 처음에 이 댓글을 달았는데.. 정답 결과랑 다르게 나와서 =_=;;
-
KJS
2013.04.05 13:20
죄송합니다.
제가 northwind 가 없어서...확인 없이 올렸습니다.
혹시 어떻게 다르게 나오나요?
-
이리
2013.04.05 13:57
123456789 순서대로 쿼리가 되고 7 부분이 NULL이 아니라 0으로 나옵니다.
-
화성에서왔어요
2013.04.05 14:01
답변감사합니다.KJS // ON E.EmployeeID = O.EmployeeID AND year(O.orderDate) = 1996 AND month(O.orderDate) = 7WHERE 문제인것을 알고 위 방법대로도 해봤는데 쿼리가 아래처럼 나옵니다.문제 정답이 잘못된 걸까요... 머리 싸매면서 다른 문제 풀면서 이것도 계속 보는중인데 어렵네요...Data 1 Sales Representative 0.00 0.00 140.51 0.00 0.00Data 2 Vice President, Sales 0.00 0.00 0.00 55.28 0.00Data 3 Sales Representative 55.31 0.00 58.17 0.00 25.73Data 4 Sales Representative 274.41 133.21 0.00 3.25 58.14Data 5 Sales Manager 0.00 0.00 4.56 55.36 0.00Data 6 Sales Representative 0.00 0.00 3.67 0.00 11.61Data 7 Sales Representative 0.00 0.00 0.00 0.00 0.00Data 8 Inside Sales Coordinator 48.29 66.29 0.00 0.00 0.00Data 9 Sales Representative 0.00 146.06 0.00 0.00 148.33TTL NULL NULL 378.01 345.56 206.91 113.89 243.81 -
이리
2013.04.05 14:19
음.. 조잡하지만 정답과 같은 결과가 나오는 쿼리입니다.
이런 쿼리를 원한건 아닌거 같긴 하지만요;;
SELECT CASE WHEN(E.employeeID BETWEEN 1 AND 9) THEN 'DATA' END AS [DataType]
, E.employeeID AS employeeID
, E.title AS title
, isnull(sum(CASE WHEN(datepart(dw, O.orderDate) = 2) THEN O.freight END),0) AS [MonFreight]
, isnull(sum(CASE WHEN(datepart(dw, O.orderDate) = 3) THEN O.freight END),0) AS [TueFreight]
, isnull(sum(CASE WHEN(datepart(dw, O.orderDate) = 4) THEN O.freight END),0) AS [WedFreight]
, isnull(sum(CASE WHEN(datepart(dw, O.orderDate) = 5) THEN O.freight END),0) AS [ThrFreight]
, isnull(sum(CASE WHEN(datepart(dw, O.orderDate) = 6) THEN O.freight END),0) AS [FriFreight]
FROM employees AS E
LEFT OUTER JOIN orders AS O ON E.EmployeeID = O.EmployeeID
WHERE year(O.orderDate) = 1996 AND month(O.orderDate) = 7
GROUP BY E.employeeID, E.title
UNION ALL
SELECT CASE WHEN(E.employeeID BETWEEN 1 AND 9) THEN 'DATA' END AS [DataType]
, E.employeeID AS employeeID
, E.title AS title
, sum(CASE WHEN(datepart(dw, O.orderDate) = 2) THEN O.freight END) AS [MonFreight]
, sum(CASE WHEN(datepart(dw, O.orderDate) = 3) THEN O.freight END) AS [TueFreight]
, sum(CASE WHEN(datepart(dw, O.orderDate) = 4) THEN O.freight END) AS [WedFreight]
, sum(CASE WHEN(datepart(dw, O.orderDate) = 5) THEN O.freight END) AS [ThrFreight]
, sum(CASE WHEN(datepart(dw, O.orderDate) = 6) THEN O.freight END) AS [FriFreight]
FROM employees AS E
LEFT OUTER JOIN orders AS O ON E.EmployeeID = O.EmployeeID AND year(O.orderDate) = 1996 AND month(O.orderDate) = 7
WHERE O.freight IS NULL
GROUP BY E.employeeID, E.title
UNION ALL
SELECT 'TTL' AS [DataType]
, NULL AS title
, NULL AS employeeID
, isnull(sum(CASE WHEN(datepart(dw, O.orderDate) = 2) THEN O.freight END),0) AS [MonFreight]
, isnull(sum(CASE WHEN(datepart(dw, O.orderDate) = 3) THEN O.freight END),0) AS [TueFreight]
, isnull(sum(CASE WHEN(datepart(dw, O.orderDate) = 4) THEN O.freight END),0) AS [WedFreight]
, isnull(sum(CASE WHEN(datepart(dw, O.orderDate) = 5) THEN O.freight END),0) AS [ThrFreight]
, isnull(sum(CASE WHEN(datepart(dw, O.orderDate) = 6) THEN O.freight END),0) AS [FriFreight]
FROM employees AS E
LEFT OUTER JOIN orders AS O ON E.EmployeeID = O.EmployeeID
WHERE year(O.orderDate) = 1996 AND month(O.orderDate) = 7
-
KJS
2013.04.05 17:14
아래 부분 때문에 null 이 아닌 0 값이 나오는 것 같습니다.
즉 아래의 isnull 함수로 인해 모든 null 값이 0 으로 바뀌게 됩니다.
isnull(sum(CASE WHEN(datepart(dw, O.orderDate) = 2) THEN O.freight END),0)
위의 부분에서 O.EmployeeID 이 null 인지 아닌지 체크 하는 조건을 넣으면 원하는 결과를 얻을수 있을것 같습니다.
sum(CASE WHEN(datepart(dw, O.orderDate) = 2) and O.EmployeeID is not null THEN isnull(O.freight END,0) ) end
감사합니다.
-
화성에서왔어요
2013.04.08 14:23
어렵군요... 문제를 많이 꼬아놓은거군요..
답변주신분들 모두 감사합니다.
음.. UNION을 쓰면 정답대로 나오긴 하는데..
쿼리가 좀 너저분 해지네요.