在Excel中没有聚合的动态数据透视表

时间:2018-04-09 06:55:54

标签: sql-server excel pivot-table

我知道之前曾多次询问此事,但它始终使用Sum或Max或其他内容或计数。我需要将行精确地转换为列。数据如下:

ID  User    DateTime
--------------------------------
2   UserA   2018-04-01  22:45:35
2   UserA   2018-04-01  13:50:40
2   UserA   2018-04-02  05:56:38
2   UserA   2018-04-02  14:19:44
2   UserA   2018-04-02  14:23:13
2   UserA   2018-04-03  05:55:32
2   UserA   2018-04-03  05:58:33
2   UserA   2018-04-03  14:34:32
2   UserA   2018-04-05  13:08:37
3   UserB   2018-04-01  13:50:35
3   UserB   2018-04-01  22:45:27
3   UserB   2018-04-02  05:51:17
3   UserB   2018-04-02  14:24:00
3   UserB   2018-04-03  05:54:43
3   UserB   2018-04-03  14:35:21
3   UserB   2018-04-04  13:09:59

现在我需要在Microsoft Excel中使用它。

ID  User    2018.04.01  2018.04.02  2018.04.03  2018.04.04  2018.04.05
-----------------------------------------------------------------------
2   UserA   13:50:40    05:56:38    05:55:32                13:08:37
2   UserA   22:45:35    14:19:44    05:58:33            
2   UserA               14:23:13    14:34:32            
3   UserB   13:50:35    05:51:17    05:54:43    13:09:59    
3   UserB   22:45:27    14:24:00    14:35:21            

我一直在摸索着互联网,但每个人都使用数据透视表来实现这一目标。我在数据透视表中尝试了各种技巧,但似乎无法将值分开。唯一可用的选项是“计数”。

我尝试使用以下SQL语句来转移日期并检索到excel。

declare @cols as nvarchar(max), @query as nvarchar(max);
declare @startDate nvarchar(max) = '1 apr 2018';
declare @endDate nvarchar(max) = '30 apr 2018';

SELECT @cols = STUFF((SELECT ',' + QUOTENAME(Tgl) FROM f_Filtered_Check(@startdate, @enddate) GROUP BY Tgl ORDER BY Tgl FOR XML Path(''), TYPE).value('.' , 'NVARCHAR(MAX)') ,1,1,'');

set @query = '
SELECT * FROM f_Filtered_Check(''' + @startdate + ''', ''' + @enddate + ''')
pivot (
    max(checktime)
    for Tgl in (' + @cols + ')
) pvt
ORDER BY UserID, SwapID';
execute(@query)

但我似乎无法在Excel中使用SQL窗口输入@startDate和@endDate参数。

感谢您的帮助。

编辑:为了清楚起见,我的目标是在Excel中获取第二个表,而第一个表来自SQL Server。我想,它可以通过两种方式完成。

  1. 使用上面的SQL语句,但我不知道如何将@startDate和@endDate参数放入Excel中的该语句。 '2018年4月1日'和'201年4月30日'应该是动态的,并且可以在excel运行该查询之前由用户设置。
  2. 在Excel中检索并转动数据。但Excel拒绝在数据透视表中输出多个数据,唯一可访问的函数是count
  3. 请原谅我的英语。

1 个答案:

答案 0 :(得分:0)

我假设你的函数生成了一个日期列表,所以我在不使用该函数的情况下进行了一些小改动,当然,你可以将它合并到以下解决方案中:

    SET NOCOUNT ON 
    IF OBJECT_ID ('tempdb..##T') IS NOT NULL DROP TABLE ##T
    DECLARE @cols NVARCHAR(MAX) = ''
    DECLARE @Pivot NVARCHAR(MAX) 
    DECLARE @Start NVARCHAR(30)= '2018-04-01'
    DECLARE @End NVARCHAR(30) = '2018-04-05'
    ;WITH T (ID , [User]  ,  [DateTime]) AS 
    (


    SELECT 2  , 'UserA' ,  CAST('2018-04-01  22:45:35' AS DATETIME) UNION ALL
    SELECT 2  , 'UserA' ,  CAST('2018-04-01  13:50:40' AS DATETIME) UNION ALL
    SELECT 2  , 'UserA' ,  CAST('2018-04-02  05:56:38' AS DATETIME) UNION ALL
    SELECT 2  , 'UserA' ,  CAST('2018-04-02  14:19:44' AS DATETIME) UNION ALL
    SELECT 2  , 'UserA' ,  CAST('2018-04-02  14:23:13' AS DATETIME) UNION ALL
    SELECT 2  , 'UserA' ,  CAST('2018-04-03  05:55:32' AS DATETIME) UNION ALL
    SELECT 2  , 'UserA' ,  CAST('2018-04-03  05:58:33' AS DATETIME) UNION ALL
    SELECT 2  , 'UserA' ,  CAST('2018-04-03  14:34:32' AS DATETIME) UNION ALL
    SELECT 2  , 'UserA' ,  CAST('2018-04-05  13:08:37' AS DATETIME) UNION ALL
    SELECT 3  , 'UserB' ,  CAST('2018-04-01  13:50:35' AS DATETIME) UNION ALL
    SELECT 3  , 'UserB' ,  CAST('2018-04-01  22:45:27' AS DATETIME) UNION ALL
    SELECT 3  , 'UserB' ,  CAST('2018-04-02  05:51:17' AS DATETIME) UNION ALL
    SELECT 3  , 'UserB' ,  CAST('2018-04-02  14:24:00' AS DATETIME) UNION ALL
    SELECT 3  , 'UserB' ,  CAST('2018-04-03  05:54:43' AS DATETIME) UNION ALL
    SELECT 3  , 'UserB' ,  CAST('2018-04-03  14:35:21' AS DATETIME) UNION ALL
    SELECT 3  , 'UserB' ,  CAST('2018-04-04  13:09:59' AS DATETIME) 

    )

    SELECT *
    INTO ##T 
    FROM T

    SELECT @cols += ',' + QUOTENAME(T.Dts)
    FROM 
    (
     SELECT  CAST(CAST([DateTime] AS DATE) AS  VARCHAR(10))
      FROM ##T
      WHERE [DateTime]>= @Start
      AND [DateTime] < DATEADD(DAY,1,@End)
      GROUP BY CAST(CAST([DateTime] AS DATE) AS  VARCHAR(10))
    ) T (Dts)

    SET @cols =  STUFF(@cols,1,1,'')



    SET @Pivot =
    'SELECT Id, [User], '+@cols+'
    FROM 
        (
        SELECT Id , [User] , CONVERT(VARCHAR(10),[Datetime], 120) AS Dt , CONVERT(VARCHAR(8),[Datetime], 108) AS [Time] , 
                ROW_NUMBER () OVER (PARTITION BY CONVERT(VARCHAR(10),[Datetime], 120) ORDER BY [DateTime]  ) seq
        FROM ##T
        WHERE [DateTime] >= '''+@Start+'''
        AND [DateTime] < '''+CONVERT(VARCHAR(10),DATEADD(DAY,1,CONVERT(DATE,@End)))+'''
        ) E
    PIVOT 
        (
        MAX([Time]) FOR dt IN ('+@cols+')
        ) q
    '
    EXEC sp_executesql @Pivot