使用Pivot将日期转换为列

时间:2016-03-18 13:11:36

标签: sql-server pivot

我不擅长使用Pivot,但我认为这是解决问题的唯一方法。

我有这个SQL

SELECT DISTINCT ADR_Adressen.AdressNrADR
, LEFT(ADR_Adressen.Name, 3) AS Name
, LEFT(ADR_Adressen.Vorname, 3) AS Vorname
, CRM_Aufgaben.TerminVon
, LAG_Artikel.ArtikelNrLAG
, CRM_AufgabenLink.MitNrPRO
FROM  ADR_Adressen
    INNER JOIN PRO_Auftraege ON ADR_Adressen.AdressNrADR = PRO_Auftraege.Kunde
    INNER JOIN CRM_Aufgaben ON PRO_Auftraege.AuftragNrPRO = CRM_Aufgaben.AuftragNrPRO
    INNER JOIN CRM_Status ON CRM_Aufgaben.StatusCRM = CRM_Status.StatusCRM
    INNER JOIN LAG_Artikel ON CRM_Aufgaben.ArtikelNrLAG = LAG_Artikel.ArtikelNrLAG
    INNER JOIN ADR_GruppenLink ON ADR_Adressen.AdressNrADR = ADR_GruppenLink.AdressNrADR
    INNER JOIN ADR_Gruppen ON ADR_GruppenLink.GruppeADR = ADR_Gruppen.GruppeADR
    INNER JOIN CRM_AufgabenLink ON CRM_Aufgaben.AufgabenNrCRM = CRM_AufgabenLink.AufgabenNrCRM
WHERE  { d '2016-03-07'} <= CRM_Aufgaben.TerminVon
   AND { d '2016-03-11'} + 1 >= CRM_Aufgaben.TerminBis
   AND CRM_AufgabenLink.MitNrPRO != 0
   AND ADR_Gruppen.GruppeADR IN ( 'KIND' ) 

这是我的结果:

enter image description here

我的愿望是获得这样的输出: enter image description here

TerminVon中的不同日期必须是包含ArtikelNrLAG + MitNrPRO值的列。如果同一个AdressNrADR在同一个日期有多个TerminVon,我必须生成更多行。 (例如,Name = Boc,Alt)

有人可以帮我吗=)

2 个答案:

答案 0 :(得分:2)

PIVOT所拥有的内容,您可以使用与此类似的查询。

SELECT  AdressNrADR,  
        Name,
        Vorname,
        [2016-03-07],
        [2016-03-08],
        [2016-03-09],
        [2016-03-10],
        [2016-03-11]
FROM (
    SELECT DISTINCT
            ADR_Adressen.AdressNrADR,
            LEFT(ADR_Adressen.Name,3) AS Name,
            LEFT(ADR_Adressen.Vorname,3) AS Vorname,
            CONVERT(VARCHAR(10), CRM_Aufgaben.TerminVon, 120) AS TerminVon, -- Convert date to yyyy-mm-dd format
            LAG_Artikel.ArtikelNrLAG + '+' + CRM_AufgabenLink.MitNrPRO AS [Value], -- Combine column values
            ROW_NUMBER() OVER 
                (PARTITION BY AdressNrADR, 
                              LEFT(ADR_Adressen.Name,3), 
                              LEFT(ADR_Adressen.Vorname,3), 
                              CAST(CRM_Aufgaben.TerminVon AS DATE) 
                        ORDER BY CRM_Aufgaben.TerminVon) Rn -- So we can get 1 row per time value
    FROM    ADR_Adressen
            INNER JOIN PRO_Auftraege ON ADR_Adressen.AdressNrADR = PRO_Auftraege.Kunde
            INNER JOIN CRM_Aufgaben ON PRO_Auftraege.AuftragNrPRO = CRM_Aufgaben.AuftragNrPRO
            INNER JOIN CRM_Status ON CRM_Aufgaben.StatusCRM = CRM_Status.StatusCRM
            INNER JOIN LAG_Artikel ON CRM_Aufgaben.ArtikelNrLAG = LAG_Artikel.ArtikelNrLAG
            INNER JOIN ADR_GruppenLink ON ADR_Adressen.AdressNrADR = ADR_GruppenLink.AdressNrADR
            INNER JOIN ADR_Gruppen ON ADR_GruppenLink.GruppeADR = ADR_Gruppen.GruppeADR
            INNER JOIN CRM_AufgabenLink ON CRM_Aufgaben.AufgabenNrCRM = CRM_AufgabenLink.AufgabenNrCRM
    WHERE   { d '2016-03-07'} <= CRM_Aufgaben.TerminVon
            AND { d '2016-03-11'} + 1 >= CRM_Aufgaben.TerminBis
            AND CRM_AufgabenLink.MitNrPRO != 0
            AND ADR_Gruppen.GruppeADR IN ('KIND') 
) t
PIVOT (
    MAX([Value]) 
    FOR TerminVon IN ([2016-03-07],[2016-03-08],[2016-03-09],[2016-03-10],[2016-03-11])
) p

如果您使该查询起作用。您的下一步是使其成为动态。

答案 1 :(得分:0)

使用t-sql的pivot功能的难点在于输出列名称必须是硬编码的。在您的示例中,我们需要知道每个日期的值并在查询中使用它,以便按日期获取匹配值。幸运的是,其他优秀的开发人员为我们带来了这种挫败感,并创建了将生成动态支点的脚本。我已经包含了两个链接,可以帮助您。

https://www.mssqltips.com/sqlservertip/2783/script-to-create-dynamic-pivot-queries-in-sql-server/

http://sqlhints.com/2014/03/18/dynamic-pivot-in-sql-server/