【问题标题】:SQL - Pivot table and group by not workingSQL - 数据透视表和组不工作
【发布时间】:2013-02-17 10:55:24
【问题描述】:

我有一张如下表:

Product     #users  Date            Count   Type
prodA       29      2013-02-27      113     Document
prodA       31      2013-03-02      152     Extraction
prodB       17      2013-02-26      40      Document
prodB       28      2013-03-02      73      Extraction

我需要在 [Type]/Count 列上使用数据透视表并获取如下表:

Product     #users  Date            Document Extraction
prodA       60      2013-03-02      113      152
prodB       45      2013-03-02      40       73

#user 列是按产品分组的总和,而日期是按产品分组的最大日期。

这是我目前得到的:

SELECT Product, 
       sum(users),
       max([Date]),  
       [Document],[Extraction] FROM Table

     PIVOT 
        ( sum([Count]) FOR [Type] IN ( Document , Extraction)) AS [QUANTITY]

     GROUP BY activity, document, extraction

但我的最终结果却给了我这样的东西:

Product     #users Date      Document Extraction
prodA       31     2013-03-02 NULL     152
prodA       29     2013-02-27 113      NULL
prodB       28     2013-03-02 NULL     73
prodB       17     2013-02-26 40       NULL

它没有按产品分组!

有什么想法吗?

编辑:

到目前为止,我已经

WITH Pivoted
AS
(
  SELECT *
  FROM table1
  PIVOT 
  ( 
    sum([Count]) FOR [Type] IN ( Document , 
                                Extraction)
  ) AS p
) 
SELECT 
  product,
  SUM(Users) AS TotalUsers,
  MAX(DAte) AS LatestDate,
  MAX(Document) AS Document,
  MAX(Extraction) AS Extraction
FROM Pivoted
GROUP BY Product;

但我上面的table1实际上是由下面的代码组成的:

WITH a
AS(
SELECT    activity, 
                username, 
                [Last Accessed] = max(DATEADD(dd, DATEDIFF(d, 0, ActDateTime), 0)), --[#Users] = count(distinct username), 
                CASE WHEN COUNT(activity)IS NOT NULL THEN 1 ELSE 0 END AS Count,
                CASE WHEN pageURL LIKE '/Document%'
                OR pageURL LIKE '/Database%' THEN 'Document' ELSE 'Extraction' END AS [Type] --into #temp
                from activitylog
                where pageURL not like '%home%' AND pageURL not like '/Default%'
                --AND ActDateTime >= @StartDate AND ActDateTime <= @EndDate
                group by activity, 
                username, 
                --department,
                DATEADD(dd, DATEDIFF(d, 0, ActDateTime), 0), 
                CASE WHEN pageURL LIKE '/Document%' OR pageURL LIKE '/Database%' THEN 'Document' ELSE 'Extraction' END 
                --order by activity--, username, department,DATEADD(dd, DATEDIFF(d, 0, ActDateTime), 0)
    )

    ,b as
    (select activity, count(distinct username) as [Users] ,
        --department ,
        max([Last Accessed]) as [Last Accessed1],count([count])as [Count],[Type] from a --into #temp1 from #temp
        group by activity, 
        --department,
        [Type]

        )  

        select * from b order by activity;

所以我的问题是,我如何将上面的代码块放在第一个 WITH AS 中?

谢谢

【问题讨论】:

    标签: sql sql-server-2008 pivot pivot-table


    【解决方案1】:

    您不能在PIVOT 表运算符中使用GROUP BY activity, document, extractionPIVOT 运算符会自动推断分组列。但是你可以这样写:

    WITH Pivoted
    AS
    (
      SELECT *
      FROM table1
      PIVOT 
      ( 
        sum([Count]) FOR [Type] IN ( Document , 
                                    Extraction)
      ) AS p
    ) 
    SELECT 
      product,
      SUM(Users) AS TotalUsers,
      MAX(DAte) AS LatestDate,
      MAX(Document) AS Document,
      MAX(Extraction) AS Extraction
    FROM Pivoted
    GROUP BY Product;
    

    SQL Fiddle Demo

    这会给你:

    | PRODUCT | TOTALUSERS |                   LATESTDATE | DOCUMENT | EXTRACTION |
    -------------------------------------------------------------------------------
    |   prodA |         60 | March, 02 2013 02:00:00+0000 |      113 |        152 |
    |   prodB |         45 | March, 02 2013 02:00:00+0000 |       40 |         73 |
    

    更新 1

    WITH a
    AS(
      SELECT    
        activity, 
        username, 
        [Last Accessed] = max(DATEADD(dd, 
                                      DATEDIFF(d, 0, ActDateTime), 
                                      0)), 
        --[#Users] = count(distinct username), 
        CASE 
          WHEN COUNT(activity) IS NOT NULL THEN 1 
          ELSE 0 
        END AS Count,
        CASE 
          WHEN pageURL LIKE '/Document%'
            OR pageURL LIKE '/Database%' THEN 'Document'
          ELSE 'Extraction' 
        END AS [Type] 
      from activitylog
      where pageURL not like '%home%' 
        AND pageURL not like '/Default%'
      group by activity, 
               username, 
               ...
    ), Pivoted
    AS
    (
      SELECT *
      FROM a
      PIVOT 
      ( 
        sum([Count]) FOR [Type] IN ( Document , 
                                     Extraction)
       ) AS p
    ) 
    SELECT 
      product,
      SUM(Users) AS TotalUsers,
      MAX(DAte) AS LatestDate,
      MAX(Document) AS Document,
      MAX(Extraction) AS Extraction
    FROM Pivoted
    GROUP BY Product; 
    

    【讨论】:

    • 我有一个问题 - 我提供的表实际上是 WITH name AS SELECT 语句的结果。因此,结合您的代码意味着我将在另一个中包含 2 个 WITH AS 语句。我似乎无法让它工作。所以我有类似 WITH Pivoted AS (SELECT * FROM (WITH Pivoted AS a...这就是我获取表格的方式)...基本上我使用了您的代码,但是代替 table1,我有另一个 (WITH AS 语句)。
    • 但它不起作用......因为我收到了许多错误,包括:关键字“WITH”附近的语法不正确。
    • @viv_acious,是的,您可以使用具有相同查询的多个 CTE,例如 WITH CTE AS(...), CTE2 AS (...) SELECT ...,您能否编辑您的问题并告诉我您尝试过的查询并给出错误?
    • 当然!实际上,我通过从我的第一个 WITH AS 创建一个#temptable 来解决这个问题。然后使用另一个 WITH AS 使用它。这种方法和你提到的有多个 CTE 之间还有什么不同吗?
    • @viv_acious - 不,但不需要临时表,正如我所说,您可以正常使用多个 CTE。类似in this demo
    【解决方案2】:

    您可以使用 CTE 实现它。

    ;WITH CTE  
    AS  
    (  
        SELECT *   
        FROM Sample  
        PIVOT  
           (SUM([COUNT]) FOR [TYPE] IN (Document, Extraction)) AS PI  
    )  
    
    SELECT   
         Product,  
         SUM(Users) AS Users,  
         MAX(Date) AS Date,  
         MAX(Document) AS Document,  
         MAX(Extraction) AS Extraction  
    FROM CTE  
    GROUP BY Product;  
    

    SQL Fiddle Demo

    【讨论】:

      猜你喜欢
      • 2012-07-07
      • 2012-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-14
      • 1970-01-01
      • 2022-12-19
      • 2013-06-09
      相关资源
      最近更新 更多