Home > Mobile >  SQL Pivot and Group By By Date and Totals
SQL Pivot and Group By By Date and Totals

Time:12-07

I am using SQL Server 13.0 Developer Edition. I can't make the correct structure for the SQL code with Pivot and Group by clauses.

I have data like;

Id OperationType Date ResultCode
1 BeginTransaction 2022-12-01 16:54:30 -28
2 BeginTransaction 2022-12-02 18:54:30 -30
3 BeginTransaction 2022-12-02 18:54:30 -30
4 BeginTransaction 2022-12-03 14:54:30 -10
5 BeginTransaction 2022-12-03 11:54:30 -5
6 BeginTransaction 2022-12-05 10:54:30 -3

and I want to see total number of ResultCodes per day but I want to generate ResultCode columns dynamicly because I have so much different result codes. Query result should be like;

Day -3 -5 -10 -28 -30 Total
2022-12-01 0 0 0 1 0 1
2022-12-02 0 0 0 0 2 2
2022-12-03 0 1 1 0 0 2
2022-12-05 1 0 0 0 0 1

I wrote this query but it says The incorrect value "ResultCode" is supplied in the PIVOT operator.

Select * from (SELECT CAST(Date as date),
COUNT(ResultCode) as Result,
       COUNT(*) AS Totals
FROM OperationLogs 
WHERE OperationType = 'Begin'
GROUP BY CAST(StartTime as date)
) As Source
PIVOT (
COUNT(Result) FOR Result IN ([ResultCode])
) AS PivotTable
ORDER BY ForDate

Can anyone help me with how can I group by date and also have counts for ResultCodes as colums and a Total by day?

CodePudding user response:

CREATE TABLE #ResultCodes (
Id INT,
OperationType VARCHAR(50),
[Date] DateTime,
ResultCode INT
)

INSERT INTO #ResultCodes(Id,OperationType,[Date],ResultCode) VALUES
(1,'BeginTransaction','2022-12-01 16:54:30',-28),
(2,'BeginTransaction','2022-12-02 18:54:30',-30),
(3,'BeginTransaction','2022-12-02 18:54:30',-30),
(4,'BeginTransaction','2022-12-03 14:54:30',-10),
(5,'BeginTransaction','2022-12-03 11:54:30',-5),
(6,'BeginTransaction','2022-12-05 10:54:30',-3)

DECLARE @COLUMNS AS NVARCHAR(MAX)
DECLARE @QUERY  AS NVARCHAR(MAX)
    
SET @COLUMNS = STUFF((SELECT ','   QUOTENAME(ResultCode) 
             FROM #ResultCodes GROUP BY ResultCode ORDER BY ResultCode DESC
             FOR XML PATH(''), TYPE
             ).value('.', 'NVARCHAR(MAX)') 
         ,1,1,'')

SET @QUERY = N'
    SELECT [Date],' @COLUMNS ', tc AS "Total"    
    FROM (
      SELECT
        [tc] = COUNT(CAST([Date] AS date)) over(partition by CAST([Date] AS date)),
        CAST([Date] AS date) AS "Date", 
        [ResultCode]
      FROM #ResultCodes
    ) AS tb 
    PIVOT (
      COUNT([ResultCode])
      FOR [ResultCode]
      IN (
        ' @COLUMNS '
      )
    ) AS P'; 

EXEC(@QUERY)

DROP TABLE IF EXISTS #ResultCodes

enter image description here

CodePudding user response:

You can find the answer here : https://www.sqlshack.com/dynamic-pivot-tables-in-sql-server/
and below

USE [tempdb] 
IF OBJECT_ID ('[Date]') IS NOT NULL DROP TABLE [Date] 
CREATE TABLE [Date] ([Id] int , [OperationType] varchar(50) , [Date] datetime  , [ResultCode] int) 
INSERT INTO [Date] VALUES (1, 'BeginTransaction', '2022-12-01 16:54:30', -28)    , (2, 'BeginTransaction', '2022-12-02 18:54:30', -30)   , (3, 'BeginTransaction', '2022-12-02 18:54:30', -30)   , (4, 'BeginTransaction', '2022-12-03 14:54:30', -10)   , (5, 'BeginTransaction', '2022-12-03 11:54:30', -5)    , (6, 'BeginTransaction', '2022-12-05 10:54:30', -3)

DECLARE @pivotcolumns varchar(500) = STUFF((SELECT ','   QUOTENAME(CAST([ResultCode] AS varchar(20))) FROM [Date] GROUP BY [ResultCode] ORDER BY [ResultCode] FOR XML PATH('')),1,1,'')

DECLARE @SqlStatement NVARCHAR(MAX)   
SET @SqlStatement = N'
    SELECT * , SUM(' REPLACE(@pivotcolumns, ',', ' ') ') OVER (PARTITION BY CAST([Date] AS date)) AS "Total"     FROM (
      SELECT
        CAST([Date] AS date) AS "Date", [ResultCode]
      FROM [Date]
    ) AS t1
    PIVOT (
      COUNT([ResultCode])
      FOR [ResultCode]
      IN (
        ' @pivotcolumns '
      )
    ) AS PivotTable
      ';
EXEC(@SqlStatement)
  • Related