Related
I Have a table temp_customer. Schema and some data like below-
CREATE TABLE [dbo].[temp_customer](
[id] [int] IDENTITY(1,1) NOT NULL,
[company_id] [int] NOT NULL,
[created_by] [int] NULL,
[created_at] [datetime] NULL,
[code] [varchar](25) NOT NULL,
[name] [varchar](50) NULL,
)
SET IDENTITY_INSERT [dbo].[temp_customer] ON
INSERT [dbo].[temp_customer] ([id], [company_id], [created_by], [created_at], [code], [name]) VALUES (1714, 1, 1, CAST(N'2018-02-14 11:43:00.757' AS DateTime), N'STET-00001', N'Stephan Taylor')
INSERT [dbo].[temp_customer] ([id], [company_id], [created_by], [created_at], [code], [name]) VALUES (1715, 1, 1, CAST(N'2018-02-14 11:43:01.007' AS DateTime), N'TAMJ-00001', N'Tamala Jones')
INSERT [dbo].[temp_customer] ([id], [company_id], [created_by], [created_at], [code], [name]) VALUES (1716, 1, 2, CAST(N'2018-02-14 11:43:01.457' AS DateTime), N'TARB-00001', N'Taran Blauman')
INSERT [dbo].[temp_customer] ([id], [company_id], [created_by], [created_at], [code], [name]) VALUES (1718, 1, 1, CAST(N'2019-01-29 00:00:00.000' AS DateTime), N'VERD-00001', N'Veronica Dave')
INSERT [dbo].[temp_customer] ([id], [company_id], [created_by], [created_at], [code], [name]) VALUES (1719, 1, 1, CAST(N'2018-02-14 11:43:02.190' AS DateTime), N'WAYD-00001', N'Wayne Dotson')
INSERT [dbo].[temp_customer] ([id], [company_id], [created_by], [created_at], [code], [name]) VALUES (1720, 1, 2, CAST(N'2018-03-12 07:40:34.107' AS DateTime), N'LARJ-00001', N'Larry Jacobs')
INSERT [dbo].[temp_customer] ([id], [company_id], [created_by], [created_at], [code], [name]) VALUES (1721, 1, 2, CAST(N'2018-03-28 03:40:52.673' AS DateTime), N'ROBM-00002', N'Robert Matte')
INSERT [dbo].[temp_customer] ([id], [company_id], [created_by], [created_at], [code], [name]) VALUES (1722, 1, 1, CAST(N'2018-03-28 05:09:53.093' AS DateTime), N'MART-00001', N'Mark Taylor')
INSERT [dbo].[temp_customer] ([id], [company_id], [created_by], [created_at], [code], [name]) VALUES (1723, 1, 1, CAST(N'2018-03-28 05:39:19.237' AS DateTime), N'TAYT-00001', N'ALEX BRUZZI')
INSERT [dbo].[temp_customer] ([id], [company_id], [created_by], [created_at], [code], [name]) VALUES (1724, 1, 3, CAST(N'2018-04-04 04:37:29.547' AS DateTime), N'STOCK', N'STOCK')
INSERT [dbo].[temp_customer] ([id], [company_id], [created_by], [created_at], [code], [name]) VALUES (1725, 1, 3, CAST(N'2018-04-04 06:51:10.797' AS DateTime), N'AMAT-00001', N'Amanda Trezza')
INSERT [dbo].[temp_customer] ([id], [company_id], [created_by], [created_at], [code], [name]) VALUES (1726, 1, 1, CAST(N'2018-04-04 06:55:04.720' AS DateTime), N'ADRG-00001', N'Adriana Grande')
INSERT [dbo].[temp_customer] ([id], [company_id], [created_by], [created_at], [code], [name]) VALUES (1727, 1, 3, CAST(N'2018-04-05 00:00:00.000' AS DateTime), N'ISSJ-00002', N'Issac Johnes')
INSERT [dbo].[temp_customer] ([id], [company_id], [created_by], [created_at], [code], [name]) VALUES (1728, 1, 2, CAST(N'2019-01-18 00:00:00.000' AS DateTime), N'JACJ-00001', N'Jacob Jensen')
it looks like -
I would like to get output group on created_by with total_customer_created and week in which customer created as individual columns. eg in excel like -
i.e on basis of Week(starting from monday) , total customer created by 1,2,3..... etc in required date range.
Any helps appreciated in advance.
I have found one solution, it is working.
firstly a function to find weeks(with date range)
CREATE FUNCTION [dbo].[fGetWeeksList]
(
#StartDate DATETIME
,#EndDate DATETIME
)
RETURNS
TABLE
AS
RETURN
(
SELECT DATEADD(DAY,-(DATEPART(DW,DATEADD(WEEK, x.number, #StartDate))-2),DATEADD(WEEK, x.number, #StartDate)) as [StartDate]
,DATEADD(DAY,-(DATEPART(DW,DATEADD(WEEK, x.number + 1, #StartDate))-1) ,DATEADD(WEEK, x.number + 1, #StartDate)) AS [EndDate]
FROM master.dbo.spt_values x
WHERE x.type = 'P' AND x.number <= DATEDIFF(WEEK, #StartDate, DATEADD(WEEK,0,CAST(#EndDate AS DATE)))
)
And then use it in below query
select cast(cast(fGetWeeksList.startdate as date) as varchar(max)) + ' To '+cast(cast(fGetWeeksList.enddate as date) as varchar(max)) as week_range,
*
into #week_table from fGetWeeksList('01-01-2022','06-02-2022')
select users.user_cd ,
users.first_name ,
users.last_name,
count(customers.id) cust_count,
#week_table.week_range
into #cust_count
from users
inner join customers on
users.id = customers.created_by
inner join #week_table on
cast(customers.created_at as date) between #week_table.StartDate and #week_table.EndDate
group by
users.user_cd ,users.first_name ,users.last_name,
#week_table.week_range
DECLARE #columns NVARCHAR(MAX), #sql NVARCHAR(MAX);
SET #columns = N'';
SELECT #columns += N', ' + QUOTENAME(week_range)
FROM (SELECT distinct #week_table.week_range FROM #week_table
GROUP BY #week_table.week_range) AS x;
print #columns
SET #sql = N'SELECT user_cd,p.first_name,p.last_name, ' + STUFF(#columns, 1, 2, '') + '
FROM
(
SELECT p.week_range, p.user_cd,p.first_name,p.last_name, p.cust_count FROM dbo.#cust_count AS p
) AS j
PIVOT
(
SUM(cust_count) FOR week_range IN ('+ STUFF(REPLACE(#columns, ', p.[', ',['), 1, 1, '') + ')
) AS p;';
PRINT #sql;
EXEC sp_executesql #sql;
drop table #week_table
drop table #cust_count
Help In the pivot method , i dont want to keep writing all the Id is there a way to Like Do it without writing all the id
I dont know how
SELECT 'Montant' AS IdClient,
*
FROM
(
SELECT MontantTransaction,IdClient
FROM Transactions
) AS TableSource
PIVOT
(
Sum(MontantTransaction)
FOR IdClient IN( [1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14],[15],[16],[17],[18],[19],[20],[21],[22],[23],[24])
) AS TableDePivot;
i expect to see this code without the ( [1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13]....
Try this -
Sample Temp Table & Data
Create Table #Transactions
(
IdClient varchar(3),
MontantTransaction decimal(10,2)
)
insert into #Transactions values (1, 1000.00)
insert into #Transactions values (1, 200.00)
insert into #Transactions values (2, 800.00)
insert into #Transactions values (2, 700.00)
insert into #Transactions values (3, 1100.00)
insert into #Transactions values (4, 1400.00)
Query
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX);
SET #cols = STUFF((SELECT distinct ',' + QUOTENAME(c.IdClient)
FROM #Transactions c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT ''Montant'' AS IdClient, ' + #cols + ' from
(
select
MontantTransaction
, IdClient
from #Transactions
) x
pivot
(
Sum(MontantTransaction)
for IdClient in (' + #cols + ')
) p '
execute(#query)
drop table #Transactions
I have 3 table name class , Student and Religion and below data are as follows
Class Table
ClassId ClassName
1 class-1
2 class-2
3 class-3
Religion Table
ReligionId RegionName
1 Hindu
2 Muslim
Student Table
employeeid StudentName religionid dateofbirth classid
1 A 1 1990-12-04 1
2 B 2 1999-12-04 2
3 C 2 2000-12-04 1
4 D 2 1988-12-04 1
5 E 2 2003-12-04 2
6 F NULL 2002-12-04 1
How Can I achieve below record from above tables
CLASSNAME HINDU MUSLIM Noreligion
class-1 1 2 1
class-2 0 2 0
You can create the tables from the below scripts
CREATE TABLE [dbo].[class](
[ClassId] [int] IDENTITY(1,1) NOT NULL,
[ClassName] [varchar](250) NULL,
CONSTRAINT [PK_class] PRIMARY KEY CLUSTERED
(
[ClassId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[Religion](
[ReligionId] [int] NOT NULL,
[RegionName] [varchar](50) NULL,
CONSTRAINT [PK_Religion] PRIMARY KEY CLUSTERED
(
[ReligionId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[Student](
[employeeid] [int] IDENTITY(1,1) NOT NULL,
[StudentName] [varchar](150) NULL,
[religionid] [int] NULL,
[dateofbirth] [date] NULL,
[classid] [int] NULL,
CONSTRAINT [PK_Student] PRIMARY KEY CLUSTERED
(
[employeeid] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
SET IDENTITY_INSERT [dbo].[class] ON
INSERT [dbo].[class] ([ClassId], [ClassName]) VALUES (1, N'class-1')
INSERT [dbo].[class] ([ClassId], [ClassName]) VALUES (2, N'class-2')
INSERT [dbo].[class] ([ClassId], [ClassName]) VALUES (3, N'class-3')
SET IDENTITY_INSERT [dbo].[class] OFF
INSERT [dbo].[Religion] ([ReligionId], [RegionName]) VALUES (1, N'hindu')
INSERT [dbo].[Religion] ([ReligionId], [RegionName]) VALUES (2, N'muslim')
SET IDENTITY_INSERT [dbo].[Student] ON
INSERT [dbo].[Student] ([employeeid], [StudentName], [religionid], [dateofbirth], [classid]) VALUES (1, N'A', 1, CAST(N'1990-12-04' AS Date), 1)
INSERT [dbo].[Student] ([employeeid], [StudentName], [religionid], [dateofbirth], [classid]) VALUES (2, N'B', 2, CAST(N'1999-12-04' AS Date), 2)
INSERT [dbo].[Student] ([employeeid], [StudentName], [religionid], [dateofbirth], [classid]) VALUES (3, N'C', 2, CAST(N'2000-12-04' AS Date), 1)
INSERT [dbo].[Student] ([employeeid], [StudentName], [religionid], [dateofbirth], [classid]) VALUES (4, N'D', 2, CAST(N'1988-12-04' AS Date), 1)
INSERT [dbo].[Student] ([employeeid], [StudentName], [religionid], [dateofbirth], [classid]) VALUES (5, N'E', 2, CAST(N'2003-12-04' AS Date), 2)
INSERT [dbo].[Student] ([employeeid], [StudentName], [religionid], [dateofbirth], [classid]) VALUES (6, N'F', NULL, CAST(N'2002-12-04' AS Date), 1)
SET IDENTITY_INSERT [dbo].[Student] OFF
Do it require Pivot table to be use.
I was not able to made the query getting such records.
This is more conditional aggregation that pivoting. This gets you the result you're after:
SELECT C.ClassName,
COUNT(CASE R.RegionName WHEN 'Hindu' THEN 1 END) AS Hindu,
COUNT(CASE R.RegionName WHEN 'Muslim' THEN 1 END) AS Muslim,
COUNT(CASE WHEN R.RegionName IS NULL THEN 1 END) AS NoReligion
FROM dbo.class C
JOIN dbo.Student S ON C.ClassId = S.classid
LEFT JOIN dbo.Religion R ON S.religionid = R.ReligionId
GROUP BY C.ClassName;
If you don't understand the syntax, please ask.
Edit: OP has now stated that there are more religions than just the 2 they provided, and needs to be dynamic. This therefore gives:
--Additional sample row if you wish:
INSERT [dbo].[Religion] ([ReligionId], [RegionName])
VALUES (3, N'Catholic');
GO
DECLARE #SQL nvarchar(MAX);
SET #SQL = N'SELECT C.ClassName,' + NCHAR(10) +
STUFF((SELECT N',' + NCHAR(10) +
N' COUNT(CASE R.RegionName WHEN ' + QUOTENAME(R.RegionName,N'''') + N' THEN 1 END) AS ' + QUOTENAME(R.RegionName)
FROM dbo.Religion R
ORDER BY R.ReligionId
FOR XML PATH(N'')),1,2,N'') + N',' + NCHAR(10) +
N'COUNT(CASE WHEN R.RegionName IS NULL THEN 1 END) AS NoReligion' + NCHAR(10) +
N'FROM dbo.class C' + NCHAR(10) +
N' JOIN dbo.Student S ON C.ClassId = S.classid' + NCHAR(10) +
N' LEFT JOIN dbo.Religion R ON S.religionid = R.ReligionId' + NCHAR(10) +
N'GROUP BY C.ClassName;';
SELECT #SQL;
EXEC sp_executesql #SQL;
This is a Pivot with dynamic columns. You can have unknown number of Religions
DECLARE #cols AS NVARCHAR(MAX), #sql AS NVARCHAR(MAX);
SET #cols = STUFF((SELECT distinct ',' + QUOTENAME(ReligionName)
FROM Religion c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
Set #sql = '
SELECT ClassId, '+ #cols + ',[NoReligion]
FROM
(
Select
IIf (ReligionName IS NULL, ''NoReligion'', ReligionName) As ReligionName,
employeeid,s.ClassId
From
Student s INNER JOIN
Class ON s.classid = Class.ClassId FULL OUTER JOIN
Religion ON s.religionid = Religion.ReligionId) As src
Pivot
(
Count(employeeid)
FOR ReligionName IN('+#cols+',[NoReligion])
) As pvt'
EXECUTE sp_executesql #sql
I have to send a weekly report to the Administrator from a website. The weekly report looks something like below image.
ATV (Average Transaction Value) and UPT (Units per transaction)
Table schema and sample data are given below
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Sale](
[Id] [nvarchar](128) NOT NULL,
[UserId] [nvarchar](128) NOT NULL,
[StoreId] [nvarchar](128) NOT NULL,
[SaleAmount] [decimal](18, 2) NOT NULL,
[CreatedDate] [datetime] NOT NULL,
[Note] [nvarchar](max) NULL,
[ATV] [decimal](18, 2) NOT NULL DEFAULT ((0)),
[UPT] [decimal](18, 2) NOT NULL DEFAULT ((0)),
CONSTRAINT [PK_dbo.Sale] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
/****** Object: Table [dbo].[Store] Script Date: 12-Jun-17 2:20:36 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Store](
[Id] [nvarchar](128) NOT NULL,
[Title] [nvarchar](1000) NOT NULL,
[Address1] [nvarchar](100) NULL,
[Address2] [nvarchar](100) NULL,
[Address3] [nvarchar](100) NULL,
[City] [nvarchar](100) NULL,
[State] [nvarchar](100) NULL,
[Country] [nvarchar](100) NULL,
[ZipCode] [nvarchar](100) NULL,
[Telephone1] [nvarchar](100) NULL,
[Telephone2] [nvarchar](100) NULL,
[Telephone3] [nvarchar](100) NULL,
[Location] [geography] NULL,
[IsActive] [bit] NOT NULL DEFAULT ((0)),
[Rank] [int] NOT NULL DEFAULT ((0)),
CONSTRAINT [PK_dbo.Store] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
INSERT [dbo].[Sale] ([Id], [UserId], [StoreId], [SaleAmount], [CreatedDate], [Note], [ATV], [UPT]) VALUES (N'11', N'9d5626d9-a71e-4116-bae5-4e6d736986c3', N'c71c82aa-2ad0-4599-b6d2-17a21a7b98da', CAST(9000.00 AS Decimal(18, 2)), CAST(N'2017-06-04 10:50:04.997' AS DateTime), N'5th', CAST(16.00 AS Decimal(18, 2)), CAST(27.00 AS Decimal(18, 2)))
GO
INSERT [dbo].[Sale] ([Id], [UserId], [StoreId], [SaleAmount], [CreatedDate], [Note], [ATV], [UPT]) VALUES (N'12', N'9d5626d9-a71e-4116-bae5-4e6d736986c3', N'c71c82aa-2ad0-4599-b6d2-17a21a7b98da', CAST(8000.00 AS Decimal(18, 2)), CAST(N'2017-06-05 10:50:04.997' AS DateTime), N'4th', CAST(15.00 AS Decimal(18, 2)), CAST(26.00 AS Decimal(18, 2)))
GO
INSERT [dbo].[Sale] ([Id], [UserId], [StoreId], [SaleAmount], [CreatedDate], [Note], [ATV], [UPT]) VALUES (N'13', N'9d5626d9-a71e-4116-bae5-4e6d736986c3', N'c71c82aa-2ad0-4599-b6d2-17a21a7b98da', CAST(7000.00 AS Decimal(18, 2)), CAST(N'2017-06-06 10:50:04.997' AS DateTime), N'3rd', CAST(14.00 AS Decimal(18, 2)), CAST(25.00 AS Decimal(18, 2)))
GO
INSERT [dbo].[Sale] ([Id], [UserId], [StoreId], [SaleAmount], [CreatedDate], [Note], [ATV], [UPT]) VALUES (N'14', N'9d5626d9-a71e-4116-bae5-4e6d736986c3', N'c71c82aa-2ad0-4599-b6d2-17a21a7b98da', CAST(6000.00 AS Decimal(18, 2)), CAST(N'2017-06-07 10:50:04.997' AS DateTime), N'second', CAST(13.00 AS Decimal(18, 2)), CAST(24.00 AS Decimal(18, 2)))
GO
INSERT [dbo].[Sale] ([Id], [UserId], [StoreId], [SaleAmount], [CreatedDate], [Note], [ATV], [UPT]) VALUES (N'15', N'9d5626d9-a71e-4116-bae5-4e6d736986c3', N'c71c82aa-2ad0-4599-b6d2-17a21a7b98da', CAST(5000.00 AS Decimal(18, 2)), CAST(N'2017-06-08 10:50:04.997' AS DateTime), N'TEST', CAST(12.00 AS Decimal(18, 2)), CAST(23.00 AS Decimal(18, 2)))
GO
INSERT [dbo].[Sale] ([Id], [UserId], [StoreId], [SaleAmount], [CreatedDate], [Note], [ATV], [UPT]) VALUES (N'16', N'9d5626d9-a71e-4116-bae5-4e6d736986c3', N'c71c82aa-2ad0-4599-b6d2-17a21a7b98da', CAST(10000.00 AS Decimal(18, 2)), CAST(N'2017-06-09 10:50:04.997' AS DateTime), N'6th', CAST(17.00 AS Decimal(18, 2)), CAST(28.00 AS Decimal(18, 2)))
GO
INSERT [dbo].[Sale] ([Id], [UserId], [StoreId], [SaleAmount], [CreatedDate], [Note], [ATV], [UPT]) VALUES (N'17', N'9d5626d9-a71e-4116-bae5-4e6d736986c3', N'c71c82aa-2ad0-4599-b6d2-17a21a7b98da', CAST(888.00 AS Decimal(18, 2)), CAST(N'2017-06-10 10:43:49.693' AS DateTime), N'test test2', CAST(12.00 AS Decimal(18, 2)), CAST(13.00 AS Decimal(18, 2)))
GO
INSERT [dbo].[Store] ([Id], [Title], [Address1], [Address2], [Address3], [City], [State], [Country], [ZipCode], [Telephone1], [Telephone2], [Telephone3], [Location], [IsActive], [Rank]) VALUES (N'67586972-6694-444a-9426-a0e6e4066015', N'store 3', N'1', N'Unnamed Road', NULL, N'Richmond', N'England', N'United Kingdom', N'DL11 6RR', NULL, NULL, NULL, NULL, 1, 3)
GO
INSERT [dbo].[Store] ([Id], [Title], [Address1], [Address2], [Address3], [City], [State], [Country], [ZipCode], [Telephone1], [Telephone2], [Telephone3], [Location], [IsActive], [Rank]) VALUES (N'68ece12f-c3e7-4705-88eb-2a0da2d7c1cc', N'Test Product', N'tesadf', N'323', N'asdf', N'sdf23', N'234', N'United Kingdom', N'234', NULL, NULL, NULL, NULL, 1, 4)
GO
INSERT [dbo].[Store] ([Id], [Title], [Address1], [Address2], [Address3], [City], [State], [Country], [ZipCode], [Telephone1], [Telephone2], [Telephone3], [Location], [IsActive], [Rank]) VALUES (N'c71c82aa-2ad0-4599-b6d2-17a21a7b98da', N'Store 1', N'Greenhillstairs', NULL, NULL, N'Moffat', N'Scotland', N'United Kingdom', N'DG10 9SP', NULL, NULL, NULL, 0xE6100000010C5278753348B04B406FEE5465841C0CC0, 1, 1)
GO
INSERT [dbo].[Store] ([Id], [Title], [Address1], [Address2], [Address3], [City], [State], [Country], [ZipCode], [Telephone1], [Telephone2], [Telephone3], [Location], [IsActive], [Rank]) VALUES (N'f26f67f1-e8f7-44a4-aaac-e861d18d54f3', N'Store 2', N'Lythe Fell Road', NULL, NULL, NULL, N'England', N'United Kingdom', NULL, NULL, NULL, NULL, 0xE6100000010C640D72721A054B40729472ADACD303C0, 1, 2)
GO
Below pivot query
DECLARE #DynamicPivotQuery AS NVARCHAR(MAX)
DECLARE #ColumnName AS NVARCHAR(MAX)
declare #fromDate AS NVARCHAR(MAX)
set #fromDate=CAST('2017-06-04 10:50:04.997' AS DATE)
SELECT CAST(CreatedDate AS DATE) [Date], sum(saleamount) [SaleTotal], ATV,UPT
INTO #PivotSalesData2
FROM sale
where createddate>='2017-06-04 10:50:04.997'
GROUP BY CAST(Createddate AS DATE),storeid,ATV,UPT
--Get distinct values of the PIVOT Column
SELECT #ColumnName= ISNULL(#ColumnName + ',','')
+ QUOTENAME([Date])
FROM #PivotSalesData2
print #columnName
--Prepare the PIVOT query using the dynamic
SET #DynamicPivotQuery =
N'SELECT * from (SELECT (select Title from store where id=storeid ) storeid, CAST(CreatedDate AS DATE) [Date],
sum(atv) [atv]
FROM Sale
where createddate>=#fromDate
GROUP BY CAST(CreatedDate AS DATE),storeid,atv) AS DailyData
PIVOT( sum([atv])
FOR [Date] IN (' + #ColumnName + ')) AS PVTTable'
print #DynamicPivotQuery
--Execute the Dynamic Pivot Query
EXEC sp_executesql #DynamicPivotQuery , N'#fromDate nvarchar(max)', #fromDate = #fromDate
Generate following output
enter image description here
But I need ATV and UPT column values under each date column
This I have tested with your sample data.
Let me know the final output that you are looking for and you output and input should in tandem.
SET #DynamicPivotQuery =
N'
SELECT * from
(select UserId,sum( [ATV])atv
,DATENAME(dw,CreatedDate) createddate
FROM #Sale
group by userid,createddate
) AS DailyData
PIVOT( sum(atv)
FOR createddate IN ('+#ColumnName+')
) AS PVTTable
union ALL
SELECT * from
(select UserId,sum( [UPT])[UPT]
,DATENAME(dw,CreatedDate) createddate
FROM #Sale
group by userid,createddate
) AS DailyData
PIVOT( sum(upt)
FOR createddate IN ('+#ColumnName+')
) AS PVTTable
'
print #DynamicPivotQuery
exec (#DynamicPivotQuery)
I'm trying to pivot without aggregation, and running into a bit of a wall.
Here's the sample T-SQL I'm trying to get to work:
declare #optionalFields table (ParentId int, Name nvarchar(50), Value nvarchar(50));
insert into #optionalFields values (1, 'Field1', 'Foo');
insert into #optionalFields values (1, 'Field2', 'Bar');
insert into #optionalFields values (1, 'Field3', '42');
insert into #optionalFields values (2, 'Field1', 'Bar');
insert into #optionalFields values (2, 'Field2', 'Foo');
insert into #optionalFields values (2, 'Field3', '24');
declare #data table (Id int, Name nvarchar(50));
insert into #data values (1, 'Test record 1');
insert into #data values (2, 'Test record 2');
declare #joined table (Id int, Name nvarchar(50), OptionalFieldName nvarchar(50), OptionalFieldValue nvarchar(50));
insert into #joined
select
data.Id
,data.Name
,opt.Name
,opt.Value
from #data data
inner join #optionalFields opt on data.Id = opt.ParentId
declare #cols as nvarchar(max) =
stuff((select distinct ',' + quotename(OptionalFieldName) from #joined for xml path(''), type).value('.', 'nvarchar(max)'), 1, 1, '');
select * into #tmp from #joined
-- just to see that it's returning the expected values (it does)
select
Id
,Name
,OptionalFieldName
,OptionalFieldValue
,row_number() over (partition by Id order by Id) RN
from #tmp -- this is the FROM clause in the below dynamic-sql query
declare #query as nvarchar(max) = '
select Id, Name, ' + #cols + '
from (select Id, Name, OptionalFieldName, OptionalFieldValue, row_number() over (partition by Id order by Id) RN from #tmp) src
pivot (max(OptionalFieldName) for RN in (' + #cols + ')) pvt';
execute(#query);
drop table #tmp;
SSMS is giving me 2 errors:
Msg 8114, Level 16, State 1, Line 4
Error converting data type nvarchar to bigint.
Msg 473, Level 16, State 1, Line 4
The incorrect value "Field1" is supplied in the PIVOT operator.
The "debug" select statement is returning this:
The article (link above) seemed very promising, however I can't seem to be able to get it to work. What am I doing wrong? Or is this article outright wrong and what I'm trying to do is impossble?
I've seen a number of similar SO questions, but either they involved all-numeric fields that could "just work" with aggregation, or they involved known columns that could be implemented as simple joins - I don't know what OptionalFieldName values I'm going to be selecting, and the OptionalFieldValue values are strings that simply can't be aggregated, at least AFAIK.
I'm a bit confused on why you are trying to trick this using row_number(). Even though you have string values, you can still aggregate it - you just need to use max or min to get the result.
I'd always recommend trying to write your query with hard-coded values first, especially when using PIVOT before even attempting to use dynamic SQL. I'm unsure why you can't just write the query this way:
select Id, Name, Field1, Field2, Field3
from
(
select
Id
,Name
,OptionalFieldName
,OptionalFieldValue
from #tmp
) d
pivot
(
max(OptionalFieldValue)
for OptionalFieldName in (Field1, Field2, Field3)
) piv;
See a Demo.
Then if you really need dynamic SQL, you would just write it:
declare #optionalFields table (ParentId int, Name nvarchar(50), Value nvarchar(50));
insert into #optionalFields values (1, 'Field1', 'Foo');
insert into #optionalFields values (1, 'Field2', 'Bar');
insert into #optionalFields values (1, 'Field3', '42');
insert into #optionalFields values (2, 'Field1', 'Bar');
insert into #optionalFields values (2, 'Field2', 'Foo');
insert into #optionalFields values (2, 'Field3', '24');
declare #data table (Id int, Name nvarchar(50));
insert into #data values (1, 'Test record 1');
insert into #data values (2, 'Test record 2');
declare #joined table (Id int, Name nvarchar(50), OptionalFieldName nvarchar(50), OptionalFieldValue nvarchar(50));
insert into #joined
select
data.Id
,data.Name
,opt.Name
,opt.Value
from #data data
inner join #optionalFields opt on data.Id = opt.ParentId
declare #cols as nvarchar(max);
set #cols = stuff((select distinct ',' + quotename(OptionalFieldName)
from #joined
for xml path(''), type).value('.', 'nvarchar(max)'), 1, 1, '');
select * into #tmp from #joined
DECLARE #query AS NVARCHAR(MAX)
set #query = 'SELECT Id, Name,' + #cols + '
from
(
select Id
,Name
,OptionalFieldName
,OptionalFieldValue
from #tmp
) x
pivot
(
max(OptionalFieldValue)
for OptionalFieldName in (' + #cols + ')
) p '
execute(#query);
See Demo. Both versions appear to give the result that you have requested.
EDIT: This answer is here only to show another way to accomplish this pivoting. The answer from #bluefeet is the best solution!
Hope I understand what you need right:
declare #optionalFields table (ParentId int, Name nvarchar(50), Value nvarchar(50));
insert into #optionalFields values (1, 'Field1', 'Foo');
insert into #optionalFields values (1, 'Field2', 'Bar');
insert into #optionalFields values (1, 'Field3', '42');
insert into #optionalFields values (2, 'Field1', 'Bar');
insert into #optionalFields values (2, 'Field2', 'Foo');
insert into #optionalFields values (2, 'Field3', '24');
declare #data table (Id int, Name nvarchar(50));
insert into #data values (1, 'Test record 1');
insert into #data values (2, 'Test record 2');
select
data.Id
,data.Name
,opt.Name as Name1
,opt.Value into #tmp
from #data data
inner join #optionalFields opt on data.Id = opt.ParentId
declare #cols as nvarchar(max) =
stuff((select distinct ',' + quotename(Name1) from #tmp for xml path(''), type).value('.', 'nvarchar(max)'), 1, 1, '');
DECLARE #cols1 as nvarchar(max) =
stuff((select distinct +',MAX(CASE WHEN (pvt1.'+quotename(Name1) +' = ros.RN AND pvt1.id = ros.id) THEN ros.Value ELSE NULL END) as '+quotename(Name1) from #tmp for xml path(''), type).value('.', 'nvarchar(max)'), 1, 1, '');
declare #query as nvarchar(max) = '
;WITH cte AS(
SELECT * FROM #tmp
),
ros AS (
SELECT ROW_NUMBER() OVER (partition by Id order by Id) AS [RN],id,Value
FROM cte),
pvt1 AS (
select *
from (select Id, Name, Name1, row_number() over (partition by Id order by Id) RN
from cte) src
pivot (max(RN) for Name1 in ('+#cols+')) pvt)
SELECT pvt1.ID,
pvt1.Name,
'+#cols1+'
FROM pvt1
CROSS JOIN ros
GROUP BY pvt1.ID,
pvt1.Name'
execute(#query);
drop table #tmp
Result:
ID Name Field1 Field2 Field3
1 Test record 1 Foo Bar 42
2 Test record 2 Bar Foo 24
And if you add more Fields like insert into #optionalFields values (2, 'Field4', '15');, you will get:
ID Name Field1 Field2 Field3 Field4
1 Test record 1 Foo Bar 42 NULL
2 Test record 2 Bar Foo 24 15