【问题标题】:SQL pivot table on text value文本值的 SQL 数据透视表
【发布时间】:2018-09-03 09:57:30
【问题描述】:

我正在尝试在 SQL 中转换以下数据集。

SELECT  ParticipantID,
        ContactReasonTypeID,
        Completed = CASE WHEN Returned IS NOT NULL
                        THEN    'Completed'
                        ELSE 'Not completed'
                    END
FROM    ContactReason
WHERE   ContactReasonTypeID = 40 -- M4
UNION
SELECT  ParticipantID,
        ContactReasonTypeID,
        Completed = CASE WHEN Returned IS NOT NULL
                        THEN    'Completed'
                        ELSE 'Not completed'
                    END
FROM    ContactReason
WHERE   ContactReasonTypeID = 80 -- M8

结果如下:

ParticipantID | QuestionnaireID  | Completed
1               40                 'Completed'
1               80                 'Not completed'
2               40                 'Completed'
2               80                 'Completed'
3               40                 'Completed'
3               80                 'Not completed'
4               40                 'Completed'
4               80                 'Not completed'

我想要的是像这样旋转结果(其中 M4 是 QuestionnaireID 40,M8 是 80):

ParticipantID | M4           | M8
1               'Completed'    'Not completed'
2               'Completed'    'Completed'
3               'Completed'    'Not completed'
4               'Completed'    'Not completed'

我正在为如何旋转表格而苦苦挣扎。我当前的 SQL 如下并导致错误。我尝试根据其他帖子切换列,但无法确定需要什么:

SELECT  *
FROM    (
    SELECT  ParticipantID,
            ContactReasonTypeID,
            Completed = CASE WHEN Returned IS NOT NULL
                            THEN    'Completed'
                            ELSE 'Not completed'
                        END
    FROM    ContactReason
    WHERE   ContactReasonTypeID = 40
    UNION
    SELECT  ParticipantID,
            ContactReasonTypeID,
            Completed = CASE WHEN Returned IS NOT NULL
                            THEN    'Completed'
                            ELSE 'Not completed'
                        END
    FROM    ContactReason
    WHERE   ContactReasonTypeID = 80
) AS tbl
PIVOT (
    MAX(Returned)
    FOR ContactReasonTypeID IN ([M4],[M8])
) AS pvt
ORDER BY ParticipantID

【问题讨论】:

    标签: sql sql-server tsql pivot


    【解决方案1】:

    您可以为此使用命令PIVOT

    DECLARE @t table(ParticipantID INT, QuestionnaireID INT, Completed varchar(20))
    INSERT @t values
    (1,40,'Completed'),(1,80,'Not completed'),(2,40,'Completed'),
    (2,80,'Completed'),(3,40,'Completed'),(3,80,'Not completed'),
    (4,40,'Completed'),(4,80,'Not completed')
    
    
    SELECT ParticipantID, [40] M4, [80] M8
    FROM @t
    PIVOT
      (min(COMPLETED)  
    FOR QuestionnaireID
      in([40],[80])  
    )AS p
    ORDER BY ParticipantID
    

    结果:

    ParticipantID   M4          M8
    1               Completed   Not completed
    2               Completed   Completed
    3               Completed   Not completed
    4               Completed   Not completed
    

    【讨论】:

      【解决方案2】:

      你可以试试下面的代码:

      SELECT  DISTINCT CR.ParticipantID,
              (SELECT CASE
                          WHEN Returned IS NOT NULL
                          THEN 'Completed'
                          ELSE 'Not completed'
                      END M4
                 FROM ContactReason
                WHERE ContactReasonTypeID = 40 --M4
                  AND ParticipantID = CR.ParticipantID) M4,
              (SELECT CASE
                          WHEN Returned IS NOT NULL
                          THEN 'Completed'
                          ELSE 'Not completed'
                      END M4
                 FROM ContactReason
                WHERE ContactReasonTypeID = 80 --M8
                  AND ParticipantID = CR.ParticipantID) M8
      FROM    ContactReason CR
      WHERE   CR.ContactReasonTypeID IN (40, 80) -- M4 and M8
      

      【讨论】:

      • 这种方法效果很好,但是由于使用了数据透视表,我标记了选定的答案。
      【解决方案3】:

      你可以试试这个:

      SELECT q.ParticipantID, 
                        CASE WHEN min(q.QuestionnaireID) = 40
                              THEN min(q.Completed)
                          END as M4,
                         CASE WHEN max(q.QuestionnaireID) = 80
                              THEN max(q.Completed)
                          END as M8
        FROM
      (
      SELECT  ParticipantID,
              ContactReasonTypeID,
              Completed = CASE WHEN Returned IS NOT NULL
                              THEN    'Completed'
                              ELSE 'Not completed'
                          END
      FROM    ContactReason
      WHERE   ContactReasonTypeID = 40 -- M4
      UNION
      SELECT  ParticipantID,
              ContactReasonTypeID,
              Completed = CASE WHEN Returned IS NOT NULL
                              THEN    'Completed'
                              ELSE 'Not completed'
                          END
      FROM    ContactReason
      WHERE   ContactReasonTypeID = 80
      ) q
      GROUP BY ParticipantID;
      

      Demo 内部,将内部查询q 视为tab2

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多