2014-01-12 114 views
1

我无法与数据透视表交手,我有3个表:透视表的SQL Server 2008

AccidentType:

AccidentTypeID Description 
1    Type1 
2    Type2 
3    Type3 
4    Type4 

CaseAccidentType:

AccidentTypeID CaseID 
1    1000 
2    1000 
3    1001 

案例:

CaseID Name 
1000 Case A 
1001 Case B 

案例是主要表格e用caseaccidenttype作为事故类型的链接表。每个案例可以有多个事故类型。

我想是这样的:

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

看起来像一个透视表,但我只是不能想出办法来的。

更新: 会有很多AccidentTypes是否可以动态生成列标题。

+1

它会一直是type1,2,3和4吗?或者它可能更多?无限? – MrSimpleMind

+0

会有很多不同的类型。是否有可能通过硬编码类型来解决这个问题? – Jammy

回答

1

测试数据

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') 

查询

;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 

结果集

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

@BogdanSahlean haha​​ha干杯朋友:) –

+0

我注意到你最后一次查询你加入的名称字段。名称字段不是唯一的,这仍然有效吗? – Jammy

+0

@Jammy现在看看我已经调整了代码,所以你可以加入CaseID字段。如果它不是一个独特的领域,那么这个最后的解决方案可能会给你有趣的回应,无论如何,我已经更新了解决方案以满足您的要求。现在看看,如果它帮助接受答案,请:) –

0

另一种方法 -

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]