2013-07-25 4 views
4

CASE 문으로 여러 열로 개수를 선택할 때 문제가 발생했습니다. CASE 문이 어떻게 작동하는지는 C/C++의 IF 문과 같습니다. 값이 X 인 경우 Y를 수행합니다.어떻게 알 수없는 사례가 있습니까?

이 문제를 설명하기 위해 '이름'열의 이름을 계산하고 '날짜'열을 기준으로 그룹화하는 쿼리를 제공합니다.

SELECT [Date] 
     COUNT(CASE WHEN [Name] = 'John' THEN 1 ELSE NULL END) AS 'John', 
     COUNT(CASE WHEN [Name] = 'Joe' THEN 1 ELSE NULL END) AS 'Joe', 
     COUNT(CASE WHEN [Name] = 'Moe' THEN 1 ELSE NULL END) AS 'Moe', 
     COUNT(CASE WHEN [Name] = 'Nick' THEN 1 ELSE NULL END) AS 'Nick', 
     COUNT(CASE WHEN [Name] = 'Zack' THEN 1 ELSE NULL END) AS 'Zack' 
FROM [MyDatabase].[dbo].[LogInData] 
WHERE [Date] >= '2013-07-01' 
GROUP BY [Date] 

여기서는 계산할 이름을 알고 있다고 가정합니다. 새로운 쿼리 이름과 단일 쿼리 행에 정의되지 않은 이름을 계산하려면 어떻게해야합니까? 이 방법으로 테이블의 모든 DISTINCT 이름을 동적으로 검색하고 새 이름을 코드에 추가하지 않고도 위와 같이 별도로 계산할 수 있습니까?

도움을 주셔서 감사합니다. 복잡한 쿼리 작성을 위해 SQL을 활용하는 다양한 방법을 배우려고합니다. 정확한 답변을 찾는 것이 아니라 올바른 방향으로 나를 가리켜 줄 수있는 도움이 될 것입니다. 나는 나에게 주어진 것에 반대하여 지식을 배우고 확장하기위한 모든 것입니다. 아마도 당신은 피벗 수

SELECT [Date], [Name], COUNT(*) 
    FROM ... 
    GROUP BY [Date], [Name]; 

을,하지만 당신은 반드시 쿼리에서 그렇게 할 필요가 없습니다 :

+1

이렇게하려면 동적 SQL을 사용해야합니다. 나는 [날짜], [이름], 개수 (1) ....를 선택하고 프리젠 테이션 레이어에서 피벗을 처리하도록 권하고 싶습니다. – cadrell0

+0

2008 년 또는 그 이상인 경우 –

답변

9

당신은 그것을 다른 방법으로 할 것이다. 보유하고있는 이름 (및 열 수)을 모르는 경우 동적 SQL을 사용하여 적절한 피벗을 구성해야하지만 프레젠테이션 계층에서이 정보를 조 변경하여 SQL Server에서 최적화 된 방식으로이 데이터를 반환 할 수 있습니다 할 것.

그건 그렇고, 나는 곧 bluefeet이 예를 들어 줄 것이라고 확신한다.

사실, bluefeet 거리, 그래서를 입력합니다 : 당신이 한 행에 모두 필요하지 않으면

DECLARE @date DATE = '2013-07-01'; 

DECLARE @sql NVARCHAR(MAX) = N'', @cols NVARCHAR(MAX) = N''; 

SELECT @cols += STUFF((SELECT ',' + QUOTENAME(Name) 
         FROM dbo.LoginData 
         WHERE [Date] >= @date 
         GROUP BY Name 
         FOR XML PATH('')), 1, 1, ''); 

SET @sql = N'SELECT * 
    FROM (SELECT * FROM dbo.LoginData AS d 
    WHERE [Date] >= @date 
) AS d 
    PIVOT (COUNT([Name]) FOR [Name] IN (' + @cols + ')) AS p;'; 

EXEC sp_executesql @sql, N'@date DATE', @date; 

SQLfiddle demo

+0

데이터베이스의 논리보기가 좋지 않습니다. – cadrell0

+0

남자, 너희들은 오늘 빠르다. 나는 정확한 대답이 이상적으로 필요하지 않다는 것을 바닥에 조금 더했다. 나 혼자서이 문제를 해결하는 것에 대해 더 많은 것을 배울 수있는 도움이되는 방향이라면 충분하다. 그러나 빠른 응답에 감사드립니다! – Fastidious

+0

@Fastidious 잘 SQL Server에 의해 같은 행에 반환 된 이들이 있는지 여부에 대해서는 언급하지 않았습니다. 이것이 클라이언트 측 코딩을 간소화하는 것이라면, 클라이언트 측 코드가 기존 방식대로 SQL Server에서 제공 한 데이터를 조작하도록하는 방법을 살펴볼 것을 제안합니다. –

0

는, 다음 방금 수행 할 수 있습니다

SELECT [Date], 
     [Name], 
     COUNT(*) 
FROM [MyDatabase].[dbo].[LogInData] 
WHERE [Date] >= '2013-07-01' 
GROUP BY [Date],[Name] 
+0

네, 한 행에 입력해야합니다. 내 원래의 질문에서 지정하겠습니다. 하지만이 예제를 공유해 주셔서 감사합니다. 이것은 내가 이름을 세기 다른 방법을 이해하는 데 도움이됩니다. – Fastidious

관련 문제