简体   繁体   中英

Pivot Table SQL server 2008

I can't get to grips with pivot tables, I have 3 tables:

AccidentType:

AccidentTypeID Description
1              Type1
2              Type2
3              Type3
4              Type4

CaseAccidentType:

AccidentTypeID CaseID
1              1000
2              1000
3              1001

Case:

CaseID Name
1000   Case A
1001   Case B

Case is the main table with caseaccidenttype as a link table to the accident type. Each case can have multiple accidenttypes.

I want something like:

CaseID Name    Type1 Type2 Type3 Type4
1000   Case A  True  True  False False
1001   Case B  False False True  False

Looks like a pivot table but i just cant figure it out.

Update: There will be many AccidentTypes is it possible to dynamically generate the column headings.

Test Data

DECLARE @AccidentType TABLE(AccidentTypeID INT, [Description] NVARCHAR(100))
INSERT INTO @AccidentType VALUES
(1,'Type1'),(2,'Type2'),(3,'Type3'),(4,'Type4')

DECLARE @CaseAccidentType TABLE(AccidentTypeID INT,CaseID INT)
INSERT INTO @CaseAccidentType VALUES
(1,1000),(2,1000),(3,1001)

DECLARE @Case TABLE(CaseID INT, Name NVARCHAR(100))
INSERT INTO @Case VALUES
(1000,'Case A'),(1001,'Case B')

Query

;With CTE
AS(
    SELECT *
    FROM 
    (
    SELECT  C.CaseID,C.Name, AT.[Description]
    FROM   @Case C INNER JOIN @CaseAccidentType CAT
    ON     C.CaseID = CAT.CaseID
    INNER JOIN @AccidentType AT
    ON     CAT.AccidentTypeID = AT.AccidentTypeID
    ) Q
       PIVOT
            (MAX(Name)
             FOR [Description]
             IN ([Type1],[Type2],[Type3],[Type4])
             )Pv
 )
 SELECT  CT.CaseID
       ,C.Name
       ,CASE WHEN CT.Type1 IS NOT NULL THEN 'TRUE' ELSE 'FALSE' END AS Type1
       ,CASE WHEN CT.Type2 IS NOT NULL THEN 'TRUE' ELSE 'FALSE' END AS Type2
       ,CASE WHEN CT.Type3 IS NOT NULL THEN 'TRUE' ELSE 'FALSE' END AS Type3
       ,CASE WHEN CT.Type4 IS NOT NULL THEN 'TRUE' ELSE 'FALSE' END AS Type4
FROM CTE CT INNER JOIN @Case C
ON CT.CaseID = C.CaseID

Result Set

╔════════╦════════╦═══════╦═══════╦═══════╦═══════╗
║ CaseID ║  Name  ║ Type1 ║ Type2 ║ Type3 ║ Type4 ║
╠════════╬════════╬═══════╬═══════╬═══════╬═══════╣
║   1000 ║ Case A ║ TRUE  ║ TRUE  ║ FALSE ║ FALSE ║
║   1001 ║ Case B ║ FALSE ║ FALSE ║ TRUE  ║ FALSE ║
╚════════╩════════╩═══════╩═══════╩═══════╩═══════╝

Another approach -

SELECT C.CaseID,C.[Name],AT.[Description]
INTO #NO_PIVOT
FROM [Case] C
INNER JOIN CaseAccidentType CAT
    ON CAT.CaseID = C.CaseID
INNER JOIN AccidentType AT
    ON AT.AccidentTypeID = CAT.AccidentTypeID

SELECT
    CaseID
    ,[Name]
    ,CASE WHEN SUM(Type1) > 0 THEN CAST('True' AS VARCHAR(5)) ELSE 'False' END AS [Type1]
    ,CASE WHEN SUM(Type2) > 0 THEN CAST('True' AS VARCHAR(5)) ELSE 'False' END AS [Type2]
    ,CASE WHEN SUM(Type3) > 0 THEN CAST('True' AS VARCHAR(5)) ELSE 'False' END AS [Type3]
    ,CASE WHEN SUM(Type4) > 0 THEN CAST('True' AS VARCHAR(5)) ELSE 'False' END AS [Type4]
FROM
(   SELECT
        CaseID
        ,[Name]
        ,CASE WHEN [Description] = 'Type1' AND ISNULL((SELECT COUNT(1) FROM #NO_PIVOT WHERE CaseID = NP.CaseID AND [Name] = NP.[Name]),-1) > 0
            THEN 1 ELSE 0 END AS [Type1]
        ,CASE WHEN [Description] = 'Type2' AND ISNULL((SELECT COUNT(1) FROM #NO_PIVOT WHERE CaseID = NP.CaseID AND [Name] = NP.[Name]),-1) > 0
            THEN 1 ELSE 0 END AS [Type2]
        ,CASE WHEN [Description] = 'Type3' AND ISNULL((SELECT COUNT(1) FROM #NO_PIVOT WHERE CaseID = NP.CaseID AND [Name] = NP.[Name]),-1) > 0
            THEN 1 ELSE 0 END AS [Type3]
        ,CASE WHEN [Description] = 'Type4' AND ISNULL((SELECT COUNT(1) FROM #NO_PIVOT WHERE CaseID = NP.CaseID AND [Name] = NP.[Name]),-1) > 0
            THEN 1 ELSE 0 END AS [Type4] 
    FROM #NO_PIVOT NP
)RESULTSET
GROUP BY CaseID, [Name]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM