简体   繁体   中英

Pivoting Date in SQL Server

I have the following code in SQL Server that is generating a count of users by Code and by Date :

SELECT
    code, CONVERT(DATE, created_at) Date, COUNT(account_id) UserCount
FROM 
    Code_Table
GROUP BY
    code, CONVERT(DATE, created_at)

This just generates a count of users by each unique code and date combination. I'm attempting to use the Pivot function to get:

  • the list of unique codes in the first column
  • a column for each unique date, starting in the second column
  • a count of each user associated with the date-code combinations populating the table.

One issue I'm running into is: I would like to set this query to update automatically daily, which will add an additional column with the most recent date each day. The only pivots functions I've found require a declaration of the number of columns that are being created from rows.

I understand this would be much more easily done in Excel w/ a Pivot, but I don't currently have that option.

Any advice would be much appreciated!

You need a dynamic pivot to accomplish this. You're correct that you need an explicit column list -- so you'll query your table and actually generate SQL syntax as the result, and then execute that syntax with sp_executesql.

You can find that on Stack Overflow: SQL Server dynamic PIVOT query?

A word of warning: This is usually not best practice. You won't be able to do any filtering or any date-related logic on this result set. Whatever front end reporting software you are using is probably where you want to implement the matrix/crosstab like behavior that you're getting from pivoting.

Try using this store procedure:

CREATE PROCEDURE GetData 
    -- Add the parameters for the stored procedure here
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    DECLARE @columns varchar(MAX) = '';

    SELECT @columns = @columns + '[' + CONVERT(VARCHAR,ct.created_at) + '],'  
    FROM Code_Table ct
    GROUP BY created_at
    ORDER BY created_at ASC;

    SET @columns = SUBSTRING(@columns,1,LEN(@columns) - 1);

    DECLARE @query varchar(MAX)= 'SELECT  
                                    *
                                  FROM 
                                    (SELECT code,account_id,created_at from Code_Table) AS result
                                  PIVOT 
                                    (
                                     COUNT(account_id) FOR created_at IN ('+ @columns +')
                                    ) p'
                                  ;

    EXEC (@query)
END

I built the column's header dynamically depending of existing values of dates.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM