How to make two column pivot and other as normal - sql-server

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

Related

Copy rows into same table except primary key and auto increment columns

Is it possible to copy some rows in a table excluding the primary key and auto increment columns?
I found only one solution:
create a temp table
drop primary column
Is there any easier way to do this?
INSERT INTO TableName(Column1, Column2, Column3)
SELECT Column1, Column2, Column3
FROM TableName
WHERE <<your logic to filter rows>>
Update
CREATE TABLE [dbo].[MyTable]
(
[Id] [int] IDENTITY(1,1) NOT NULL,
[Column1] [varchar](50) NOT NULL,
[Column2] [varchar](50) NOT NULL,
[Column3] [varchar](50) NOT NULL,
CONSTRAINT [PK_MyTable]
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]
GO
DECLARE #TABLE_SCHEMA Varchar(100) = 'dbo',
#TABLE_Name Varchar(100) = 'MyTable',
#TableColumns Varchar(1000),
#RequiredColumns Varchar(1000),
#SQLStatement VARCHAR(4000)
SET #TableColumns = ''
SELECT
#TableColumns = #TableColumns + Name + ' , '
FROM syscolumns
WHERE id = object_id(#TABLE_SCHEMA+'.'+#TABLE_Name)
AND Name NOT IN (SELECT col.name
FROM sys.tables tab
INNER JOIN sys.indexes pk ON tab.object_id = pk.object_id
AND pk.is_primary_key = 1
INNER JOIN sys.index_columns ic ON ic.object_id = pk.object_id
AND ic.index_id = pk.index_id
INNER JOIN sys.columns col ON pk.object_id = col.object_id
AND col.column_id = ic.column_id
WHERE tab.object_id = object_id(#TABLE_SCHEMA+'.'+#TABLE_Name))
SET #RequiredColumns = Substring(#TableColumns,1,len(#TableColumns)-1)
SELECT #SQLStatement = 'INSERT INTO MyTable (' + #RequiredColumns + ') SELECT ' + Substring(#TableColumns,1,len(#TableColumns)-1) + ' FROM '+#TABLE_SCHEMA+'.'+#TABLE_Name
-- you can add the required where condition to filter rows
EXEC(#SQLStatement)

Dynamic pivot and initialization with a constant (without sum)

I have two Tables: TbOrder and TbProduct. These tables are correlated by a condition on a number progression through the '&' operator. If the condition is true I should assign the product to the relative order.
CREATE TABLE [dbo].[TbOrder](
[Id] [bigint] NOT NULL,
[Flag] [bigint] NOT NULL,
CONSTRAINT [PK_TbOrder] 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]
GO
CREATE TABLE [dbo].[TbProduct](
[Id] [bigint] NOT NULL,
[Flag] [bigint] NOT NULL,
[Name] [varchar](50) NOT NULL,
CONSTRAINT [PK_TbProduct] 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]
GO
INSERT [dbo].[TbOrder] ([Id], [Flag]) VALUES (1, 5124)
INSERT [dbo].[TbOrder] ([Id], [Flag]) VALUES (2, 10507925)
INSERT [dbo].[TbOrder] ([Id], [Flag]) VALUES (3, 10053569)
INSERT [dbo].[TbProduct] ([Id], [Flag], [Name]) VALUES (1, 4, N'Prod1')
INSERT [dbo].[TbProduct] ([Id], [Flag], [Name]) VALUES (2, 1024, N'Prod2')
INSERT [dbo].[TbProduct] ([Id], [Flag], [Name]) VALUES (3, 4096, N'Prod3')
INSERT [dbo].[TbProduct] ([Id], [Flag], [Name]) VALUES (4, 2, N'Prod4')
INSERT [dbo].[TbProduct] ([Id], [Flag], [Name]) VALUES (5, 1, N'Prod5')
INSERT [dbo].[TbProduct] ([Id], [Flag], [Name]) VALUES (6, 8, N'Prod6')
INSERT [dbo].[TbProduct] ([Id], [Flag], [Name]) VALUES (7, 512, N'Prod7')
INSERT [dbo].[TbProduct] ([Id], [Flag], [Name]) VALUES (8, 32, N'Prod8')
INSERT [dbo].[TbProduct] ([Id], [Flag], [Name]) VALUES (9, 16, N'Prod9')
INSERT [dbo].[TbProduct] ([Id], [Flag], [Name]) VALUES (10, 128, N'Prod10')
INSERT [dbo].[TbProduct] ([Id], [Flag], [Name]) VALUES (11, 64, N'Prod11')
INSERT [dbo].[TbProduct] ([Id], [Flag], [Name]) VALUES (12, 1, N'Prod12')
INSERT [dbo].[TbProduct] ([Id], [Flag], [Name]) VALUES (13, 8192, N'Prod13')
INSERT [dbo].[TbProduct] ([Id], [Flag], [Name]) VALUES (14, 16384, N'Prod14')
The query and the result are as follow:
select o.Id OrderId, o.Flag OrderFlag, p.Id ProductId,
p.Flag ProductFlag, p.Name ProductName from TbOrder o
inner join TbProduct p on (o.Flag & p.Flag)=p.Flag
I tried with Pivot but the result compared to the first query remained unchanged (removing the line --'x').
select * from
(select o.Id OrderId, o.Flag OrderFlag, p.Id ProductId, p.Flag ProductFlag, p.Name ProductName from TbOrder o
inner join TbProduct p on (o.Flag & p.Flag)=p.Flag) t
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols += QUOTENAME(Name) + ','
FROM TbProduct
ORDER BY FLAG;
SET #cols = LEFT(#cols, LEN(#cols) - 1);
print #cols;
SELECT #query = '
SELECT t.* FROM t
PIVOT
(
--'x'
FOR t.Name IN( ' + #cols + ' )
) AS pivot_table; ';
execute(#query)
What I would like obtain instead is a single row for each order and only the product name for which the condition is true (marked with an 'x' in the order row) are columns.
I thank in advance anyone who tries to solve this.
Using your transform query, you found out allProducts and allOrders. Then you can generate all combinations using CROSS JOIN.
Now you try to match each combination with the data already on transfrom, for every match you assign X.
Now with that data you can do a DINAMIC PIVOT. I skip because looks like you know how to do it.
SQL DEMO
WITH transform as (
select o.Id OrderId, o.Flag OrderFlag, p.Id ProductId,
p.Flag ProductFlag, p.Name ProductName
from TbOrder o
inner join TbProduct p
on (o.Flag & p.Flag) = p.Flag
), allProducts as (
SELECT distinct ProductName
FROM transform
), allOrders as (
SELECT distinct OrderFlag
FROM transform
)
SELECT O.OrderFlag,
P.ProductName,
CASE WHEN T.ProductName IS NOT NULL
THEN 'X'
END as flag
INTO partial_result
FROM allProducts P
CROSS JOIN allOrders O
LEFT JOIN transform T
ON O.OrderFlag = T.OrderFlag
AND P.ProductName= T.ProductName;
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX);
SET #cols = STUFF((SELECT distinct ',' + QUOTENAME(c.ProductName)
FROM partial_result c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
SET #query = 'SELECT OrderFlag, ' + #cols + ' from
(
select OrderFlag
, ProductName
, flag
from partial_result
) x
pivot
(
max(flag)
for ProductName in (' + #cols + ')
) p ';
execute(#query);
OUTPUT

How to find out sum of dynamic columns in SQL Pivot Query

I have a stored procedure which accepts date and month as parameters that results monthly attendance sheet. And I have to find out the monthly working hours of particular employees.
CREATE TABLE [dbo].[employee] (
[EmpID] [int] IDENTITY(100,1) NOT NULL,
[Name] [varchar](50) NULL,
[DOB] [date] NULL,
[DOJ] [date] NULL,
[Email] [varchar](50) NULL,
[Mob] [varchar](50) NULL,
[Address] [varchar](max) NULL,
CONSTRAINT [PK_tbl_employee] PRIMARY KEY CLUSTERED
(
[EmpID] 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
CREATE TABLE [dbo].[Attendace] (
[EmpID] [int] NOT NULL,
[AttendaceDate] [date] NULL,
[WorkHours] [int] NULL,
[AtID] [int] IDENTITY(1,1) NOT NULL,
CONSTRAINT [PK_Attendace] PRIMARY KEY CLUSTERED
(
[AtID] 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
Stored Procedure
ALTER procedure [dbo].[sps_AttendanceShowModified] #mon int, #year int
As begin DECLARE #cols AS NVARCHAR(MAX)=''; DECLARE #query AS
NVARCHAR(MAX)='';
set #query = 'SELECT * from (
select e.Name, a.WorkHours, DAY(a.AttendaceDate) AS d1
from Attendace a, employee e
where e.EmpID = a.EmpID and
MONTH(a.AttendaceDate) = ' + CONVERT(VARCHAR(12), #mon)+ ' AND
YEAR(a.AttendaceDate) = ' + CONVERT(VARCHAR(12), #year)+ ' ) src pivot
(
max(WorkHours) for d1 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],[25],[26],[27],[28],[29],[30])
) piv'
execute(#query) end
In your are case you can add a column in your select list like following.
sum(WorkHours) over(partition by name order by (select 1)) as Total
I have created a Demo, you can have a look.
Demo Online
Your final query should look like following.
ALTER procedure [dbo].[sps_AttendanceShowModified] #mon int, #year int
As begin DECLARE #cols AS NVARCHAR(MAX)=''; DECLARE #query AS
NVARCHAR(MAX)='';
set #query = 'SELECT name,Total,[1],[2],[3] from (
select e.Name, a.WorkHours, DAY(a.AttendaceDate) AS d1, sum(WorkHours) over(partition by e.name order by (select 1)) as Total
from Attendace a, employee e
where e.EmpID = a.EmpID and
MONTH(a.AttendaceDate) = ' + CONVERT(VARCHAR(12), #mon)+ ' AND
YEAR(a.AttendaceDate) = ' + CONVERT(VARCHAR(12), #year)+ ' ) src pivot
(
max(WorkHours) for d1 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],[25],[26],[27],[28],[29],[30])
) piv'
execute(#query) end
Note: You need to include other columns in your select.

Daily report of sales using Pivot table SQL server with multiple values under each date column

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)

SQL Server : create table using variables

When trying to execute the following, I get the errors
Msg 102, Level 15, State 1, Line 9
Incorrect syntax near 'GO'.
Msg 102, Level 15, State 1, Line 11
Incorrect syntax near 'GO'.
Msg 102, Level 15, State 1, Line 13
Incorrect syntax near 'GO'.
Can someone tell me where I am going wrong? I don't understand how the syntax is wrong
DECLARE #table nvarchar(100);
DECLARE #sql nvarchar(max);
SET #table = 'FooTable';
SET #sql = N'CREATE TABLE [dbo].[' + #table + '](
[id] [int] IDENTITY(1,1) NOT NULL,
[AddedBy] [int] NOT NULL,
[AddedDate] [datetime2](7) NOT NULL,
CONSTRAINT [PK_' + #table + '] 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]
GO
ALTER TABLE [dbo].[' + #table + '] ADD CONSTRAINT [DF_' + #table + '_AddedBy] DEFAULT ((-1)) FOR [AddedBy]
GO
ALTER TABLE [dbo].[' + #table + '] ADD CONSTRAINT [DF_' + #table + '_AddedDate] DEFAULT (getutcdate()) FOR [AddedDate]
GO';
exec (#sql)
Thanks for your assistance.
SQL server is not happy about sending batches in a dynamic context using exec(). So forget about GO. Just slice up your query where GO should be and exec() slices one by one:
DECLARE #table nvarchar(100);
DECLARE #sql nvarchar(max);
SET #table = 'FooTable';
SET #sql = N'CREATE TABLE [dbo].[' + #table + '](
[id] [int] IDENTITY(1,1) NOT NULL,
[AddedBy] [int] NOT NULL,
[AddedDate] [datetime2](7) NOT NULL,
CONSTRAINT [PK_' + #table + '] 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]'
exec (#sql)
SET #sql = 'ALTER TABLE [dbo].[' + #table + '] ADD CONSTRAINT [DF_' + #table + '_AddedBy] DEFAULT ((-1)) FOR [AddedBy]'
exec (#sql)
SET #sql = 'ALTER TABLE [dbo].[' + #table + '] ADD CONSTRAINT [DF_' + #table + '_AddedDate] DEFAULT (getutcdate()) FOR [AddedDate]'
exec (#sql)
The syntax would be fine if you executed the code inside the management tool which understands the GO command as a batch separator (just like the isql and osql tools). When you execute the code using exec() the GO command is not understood, which is why you get the error.
The solution is to either remove the GO statements (or replace them with ; which ends a statement), and it will execute fine, or inline the constraints and skip the alter table statements altogether (which looks cleaner in my opinion):
SET #sql =
N'CREATE TABLE [dbo].[' + #table + '](
[id] int IDENTITY(1,1) NOT NULL,
[AddedBy] int NOT NULL CONSTRAINT [DF_' + #table + '_AddedBy] DEFAULT ((-1)),
[AddedDate] datetime2(7) NOT NULL CONSTRAINT [DF_' + #table + '_AddedDate] DEFAULT (getutcdate()) ,
CONSTRAINT [PK_' + #table + '] 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]
';
Also, there is really no need to use quoted identifiers with the types (or even the column names), so you might as well remove the brackets [].

Resources