在SQL 2008上使用pivot和group by的SQL查询

时间:2015-06-29 16:22:17

标签: sql-server-2008 group-by pivot-table date-format

我在SQL 2008中有一个打卡时钟数据库,并希望选择数据以使用数据透视和按日期(而不是时间)和名称来获取结果。所以对于一个名字,我想让同一天的所有PunchTime在同一行。

ORIGINAL TABLE                  RESULT TABLE            
| NAME   | PUNCHTIME         |  | NAME   | TIME1             | TIME2             | TIME3             | TIME4             |
------------------------------- ------------------------------------------------------------------------------------------
|   John |2015-06-01 10:00:00|  |   John |2015-06-01 10:00:00|2015-06-01 12:00:00|2015-06-01 13:00:00|2015-06-01 21:00:00|
|   John |2015-05-30 21:34:27|  |   Amy  |2015-06-01 11:14:00|2015-06-01 17:00:00|                   |                   |
|   John |2015-06-01 10:00:00|  |   Amy  |2015-06-02 09:15:00|2015-06-02 12:25:00|                   |                   |
|    Amy |2015-06-01 11:14:00|  |   Amy  |2015-06-03 17:35:00|                   |                   |                   |
|   John |2015-06-01 12:00:00|  |   John |2015-05-30 09:04:27|2015-05-30 21:34:27|                   |                   |
|   John |2015-06-01 13:00:00|
|    Amy |2015-06-01 17:00:00|
|   John |2015-06-01 21:00:00|
|    Amy |2015-06-02 09:15:00|
|    Amy |2015-06-02 12:25:00|
|    Amy |2015-06-03 17:35:00|

1 个答案:

答案 0 :(得分:0)

试试这个: -

Set Nocount On;

Declare  @PunchCount        Int = 0
        ,@PivotColumns      Varchar(Max)
        ,@Sql               Varchar(Max)

Select   @PivotColumns = ''
        ,@Sql = ''

If Object_Id('tempdb.dbo.#Punches') Is Not Null Drop Table #Punches;

Create Table #Punches
(
     RowId          Int Identity(1,1) Primary Key
    ,Name           Varchar(100)
    ,PunchTime      DateTime
)

Insert into #Punches(Name, PunchTime) Values
 ('John','2015-06-01 10:00:00')
,('John','2015-05-30 21:34:27')
,('John','2015-06-01 10:00:00')
,('Amy','2015-06-01 11:14:00')
,('John','2015-06-01 12:00:00')
,('John','2015-06-01 13:00:00')
,('Amy','2015-06-01 17:00:00')
,('John','2015-06-01 21:00:00')
,('Amy','2015-06-02 09:15:00')
,('Amy','2015-06-02 12:25:00')
,('Amy','2015-06-03 17:35:00')

Select  @PunchCount = Max(t.PunchCount)
From    (
            Select   t.Name
                    ,Dateadd(D, 0, Datediff(D, 0, t.PunchTime)) As PunchDate
                    ,Count(t.PunchTime) As PunchCount
            From    #Punches As t
            Group By t.Name
                    ,Dateadd(D, 0, Datediff(D, 0, t.PunchTime))
        ) As t

;With PC As
(
    Select  1 As PunchCount

    Union All

    Select  (PunchCount + 1)
    From    PC
    Where   PunchCount < @PunchCount
)

Select  @PivotColumns = @PivotColumns + (t.TimeCol + Cast(PC.PunchCount As varchar(10)) + ',')
From    PC
        Cross Join
        (
            Select  'Time' As TimeCol
        ) As t

Select  @Sql = 'Select  Name,' + Substring(@PivotColumns,0,Len(@PivotColumns)) +
' From  ( ' +
        ' Select     p.Name ' +
                    ' ,p.PunchTime ' +
                    ' ,Dateadd(D, 0, Datediff(D, 0, p.PunchTime)) As PunchDate ' +
                    ' ,(''Time'' + Cast((Row_Number() Over (Partition By p.Name,Dateadd(D, 0, Datediff(D, 0, p.PunchTime)) Order By p.Name,Dateadd(D, 0, Datediff(D, 0, p.PunchTime)),p.PunchTime)) As Varchar(10))) ' +
                    '  As RowNum ' +
        ' From  #Punches As p ' +
        ' ) As s ' +
    ' Pivot ' +
    ' ( ' +
    '   Max(PunchTime) ' +
    '   For RowNum In (' + Substring(@PivotColumns,0,Len(@PivotColumns)) + ') ' +
    ' ) As p '

----Print (@Sql)
Exec (@Sql)

GO