2016-09-15 1 views
2

(죄송합니다, 새 기능 SQL). 나는 사용자가 업데이트 및/또는 추가 할 수있는 다음과 같은 테이블이 :케이스 문에서 테이블의 값을 반복 할 수있는 방법

Project Type: 
ID Name 
1 Documents 
2 DVD 
3 Poster 

나는 부분에서는, 생성 각 레코드를 통해에 루프를 필요로하고 질의가 (피벗?) :

... 
     sum (case when Project.Name = Documents then 1 else 0 end) as NumOf + Documents 
     sum (case when Project.nextvalue = nextvalue then 1 else 0 end) as NumOf + nextvalue 
... 

... 그런 다음 테이블의 각 레코드에 대해 루프 스루합니다. 결과의 모습 있도록

:

ProductName NumOfDocuments NumOfDVD NumOfPoster 
Product A   6   0   4 
Product B   13   3   8 
Product C   2   0   1 

이 가능합니까? 당신이 나와 있었던 것처럼

SELECT 
    Clients.ID, 
    Products.Name, 
    sum(case when ProjectTypes.Name = 'Abstracts' then 1 else 0 end) as NumAbstracts 
FROM Clients 
INNER JOIN Products ON Clients.ID = Products.ClientID 
INNER JOIN Projects ON Products.ID = Projects.ProductID 
INNER JOIN ProjectTypes ON Projects.ProjectTypeID = ProjectTypes.ID 
GROUP BY 
    Clients.ID, 
    Products.Name, 
    Projects.ProjectTypeID 


/* 
SCHEMA 

Clients:  ID | Name 
Products:  ID | Name | Client ID 
Projects:  ID | Name | ProductID | ProjectTypeID 
ProjectTypes: ID | Name 
*/ 
+0

시도'COUNT()''GROUP BY' – Shnugo

+0

과 관련이 동적 피벗을 원하는 것 같다? – Monah

+0

@ Shnugo 나는 당신이 나를 더 가까이에 두었다고 생각한다! 감사! – theDaviator

답변

1

당신은 조건부 집계로이 작업을 수행 할 수 있습니다

편집

여기에 내 현재 쿼리입니다.

SELECT 
ProductName, 
SUM(CASE WHEN Name = 'Documents' THEN 1 ELSE 0 END) as NumOfDocuments, 
SUM(CASE WHEN Name = 'DVD' THEN 1 ELSE 0 END) as NumOfDVD, 
SUM(CASE WHEN Name = 'Poster' THEN 1 ELSE 0 END) as NumOfPoster 
FROM 
YourTable 
GROUP BY ProductName 

동적 SQL

IF OBJECT_ID('tempdb..#Clients') IS NOT NULL DROP TABLE #Clients 
IF OBJECT_ID('tempdb..#Products') IS NOT NULL DROP TABLE #Products 
IF OBJECT_ID('tempdb..#Projects') IS NOT NULL DROP TABLE #Projects 
IF OBJECT_ID('tempdb..#ProjectTypes') IS NOT NULL DROP TABLE #ProjectTypes 

CREATE TABLE #Clients (ID int, Name varchar(64)) 
CREATE TABLE #Products (ID int, Name varchar(64), ClientID int) 
CREATE TABLE #Projects (ID int, Name varchar(64), ProductID int, ProjectTypeID int) 
CREATE TABLE #ProjectTypes (ID int, Name varchar(64)) 


INSERT INTO #Clients (ID, Name) VALUES 
(1,'Client1'), 
(2,'Client2'), 
(3,'Client3'), 
(4,'Client4') 

INSERT INTO #Products (ID, Name, ClientID) VALUES 
(1,'Prod1',1), 
(2,'Prod2',1), 
(3,'Prod3',1), 
(2,'Prod2',2), 
(2,'Prod2',3), 
(3,'Prod3',3), 
(4,'Prod3',3) 

INSERT INTO #Projects (ID, Name, ProductID, ProjectTypeID) VALUES 
(1,'Proj1',1,1), 
(1,'Proj1',2,1), 
(1,'Proj1',3,1), 
(2,'Proj2',2,2), 
(2,'Proj2',3,2), 
(2,'Proj2',4,2), 
(3,'Proj3',4,3) 

INSERT INTO #ProjectTypes (ID, Name) VALUES 
(1,'ProjType1'), 
(2,'ProjType2'), 
(3,'ProjType3') 


IF OBJECT_ID('tempdb..#Summary') IS NOT NULL DROP TABLE #Summary 

SELECT 
    c.ID, 
    prod.Name as ProductName, 
    proj.Name as ProjectName, 
    projT.Name as ProjType 
INTO #Summary 
FROM #Clients c 
    INNER JOIN 
    #Products prod on prod.ClientID = c.ID 
    INNER JOIN 
    #Projects proj on proj.ProductID = prod.ID 
    INNER JOIN 
    #ProjectTypes projT on projT.ID = proj.ProjectTypeID 

SELECT * FROM #Summary 

DECLARE @DynamicPivotQuery AS NVARCHAR(MAX) 
DECLARE @ColumnName AS NVARCHAR(MAX) 

--Get distinct values of the PIVOT Column 
SELECT @ColumnName= ISNULL(@ColumnName + ',','') 
     + QUOTENAME(ProjType) 
FROM (SELECT DISTINCT ProjType FROM #Summary) AS Names 

--Prepare the PIVOT query using the dynamic 
SET @DynamicPivotQuery = 
    N'SELECT ProductName, ' + @ColumnName + ' 
    FROM #Summary 
    PIVOT(COUNT(ProjType) 
      FOR ProjType IN (' + @ColumnName + ')) AS PVTTable' 
--Execute the Dynamic Pivot Query 
EXEC sp_executesql @DynamicPivotQuery 

그래서 테이블을 사용하여, 당신은 단지이 ... 그것은 약간의 조정이 필요할 수 있습니다 실행할 수 있어야합니다.

IF OBJECT_ID('tempdb..#Summary') IS NOT NULL DROP TABLE #Summary 

SELECT 
    c.ID, 
    prod.Name as ProductName, 
    proj.Name as ProjectName, 
    projT.Name as ProjType 
INTO #Summary 
FROM Clients c 
    INNER JOIN 
    Products prod on prod.ClientID = c.ID 
    INNER JOIN 
    Projects proj on proj.ProductID = prod.ID 
    INNER JOIN 
    ProjectTypes projT on projT.ID = proj.ProjectTypeID 


DECLARE @DynamicPivotQuery AS NVARCHAR(MAX) 
DECLARE @ColumnName AS NVARCHAR(MAX) 

--Get distinct values of the PIVOT Column 
SELECT @ColumnName= ISNULL(@ColumnName + ',','') 
     + QUOTENAME(ProjType) 
FROM (SELECT DISTINCT ProjType FROM #Summary) AS Names 

--Prepare the PIVOT query using the dynamic 
SET @DynamicPivotQuery = 
    N'SELECT ProductName, ' + @ColumnName + ' 
    FROM #Summary 
    PIVOT(COUNT(ProjType) 
      FOR ProjType IN (' + @ColumnName + ')) AS PVTTable' 
--Execute the Dynamic Pivot Query 
EXEC sp_executesql @DynamicPivotQuery 

Tutorial

+0

고마워! 미리 이름 값을 알고있는 경우에 작동합니다. 그러나 그들이 변화한다면 어떨까요? – theDaviator

+0

동적 SQL을 사용하는 PIVOT. 테이블과 컬럼 이름을 알아야합니다. 네가 그 일에 많은 것을 남겼다. Like ProductName은 결과에 있지만 원래 테이블에는 없습니다. 방금 전 가정을했습니다. 여기에 좋은 예가 있습니다. SO 톤이 더 있습니다. http://sqlhints.com/2014/03/18/dynamic-pivot-in-sql-server/ – scsimon

+0

@theDaviator 동적 SQL을 추가했습니다 – scsimon