I have data in current format
and I want to get data through SQL query in
Can some one explain what should I search or how can I write SQL query with this. I'm not an expert in SQL.
You need dynamic pivot query to achieve this. try below query
declare #columns varchar(max)='',#sql nvarchar(max);
Create table #temp (Name nvarchar(max));
insert into #temp select distinct date from YourTable --inert distinct date for pivot column
SELECT #columns+=QUOTENAME(Name) + ',' from #temp
SET #columns = LEFT(#columns, LEN(#columns) - 1);
set #sql='
SELECT * FROM
(
select ID,cast(Status as int) Status,date from YourTable
) t
PIVOT(Max(Status)
FOR date IN ('+#columns+')
) AS pivot_table
'
EXEC (#Sql)
Drop Table #temp
Related
I have a table that has contact information ordered by sort order and then going down in the column.
Contacts Table:
I need to create a table where the emergency contact infomration is sorted by Columns instead of rows:
How can I do this?
Your dyanmic pivot query should be like in this demo
declare #cols nvarchar(max);
declare #query nvarchar(max);
select
sourceId,
patientId,
data,
cols= concat(col,sortOrder)
into #t
from
Contacts
UNPIVOT
(
data for col in
(
personalContactType_MisContactTypeId,
personalContactNameLast,
personalContactNameFirst
)
)up
select #cols= stuff((
select distinct ','+ quotename(cols)
from #t
for xml path('')),1,1,'')
select #cols
select #query= 'select * from #t
pivot
( max(data) for cols in ('+#cols+
'))p'
exec (#query)
In your dynamic pivot, use SortOrder to ORDER BY when creating your column list.
I have such a table with date as column name
but I would like to have these dates in one column in more than one row something like this:
Date Index
20170806 9206
20170813 8041
20170820 8861
20170827 8356
How can I do it in SQL Server
If you would like to go for more dynamic solution rather than hard coding all columns, the below scripts should work:
IF OBJECT_ID('TestTable') IS NOT NULL
DROP TABLE TestTable;
CREATE TABLE TestTable
(
[20170806] INT NOT NULL,
[20170813] INT NOT NULL,
[20170820] INT NOT NULL,
[20170827] INT NOT NULL
)
INSERT INTO TestTable VALUES (9206, 8041, 8861, 8356)
DECLARE #cols NVARCHAR(MAX),
#sql NVARCHAR(MAX)
SELECT #cols = COALESCE(#cols + ',', '') + QUOTENAME(c.COLUMN_NAME)
FROM INFORMATION_SCHEMA.[COLUMNS] AS c
WHERE c.TABLE_NAME = 'TestTable'
SET #sql = '
SELECT [Date],
[Index]
FROM TestTable
UNPIVOT([Index] FOR [Date] IN ('+ #cols +')) AS up'
exec sp_executesql #sql;
You can use UNPIVOT for this.
SELECT * FROM MyTable
UNPIVOT([Date] For [Index] IN( [20170806], [20170813], [20170820], [20170827])) UNPVT
In addition, if you want to make it dynamically, you can use this query too.
DECLARE #ColNames NVARCHAR(MAX)
= STUFF(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
(SELECT T.* FROM (VALUES(1)) AS DUMY(ID) LEFT JOIN MyTable T ON 1=2 FOR XML AUTO, ELEMENTS XSINIL )
,'<T xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">','')
,'</T>','')
,'_x0032_','2')
,' xsi:nil="true"/>','] ')
,'<',',[') ,1,1,'')
DECLARE #SqlQ NVARCHAR(MAX)
= 'SELECT * FROM MyTable UNPIVOT([Date] For [Index] IN( ' + #ColNames + ')) UNPVT'
EXEC sp_executesql #SqlQ
You could use pivot such as:
However, i dont know your exact table names
select field_names
from table_name
pivot
( index
for index in ( Date, Index)
) pivot
but a useful article to follow is
"https://technet.microsoft.com/en-us/library/ms177410(v=sql.105).aspx"
Designed the table (variable) structure as below.
Hopefully, it matches your table structure.
DECLARE #data TABLE
(
[20170806] INT,
[20170813] INT,
[20170820] INT,
[20170827] INT
)
INSERT INTO #data VALUES (9206, 8041, 8861, 8356)
SELECT * FROM #data
You can use UNPIVOT statement for this. If you have dynamic columns, check this.
SELECT [Date],[Index]
FROM
#data
UNPIVOT
(
[Index] FOR [Date] IN ([20170806], [20170813], [20170820], [20170827])
) AS unpivotTable;
and the output is
DECLARE #query VARCHAR(max)
DECLARE #years VARCHAR(max)
SELECT #years = STUFF(( SELECT DISTINCT '],[' + ltrim(str(Years)) FROM
#Inquires ORDER BY '],[' + ltrim(str(Years)) desc FOR XML
PATH('')), 1, 2, '') + ']'
SET #query = 'INSERT INTO Table_Name SELECT *
FROM (SELECT ReportDate, Company, EventType, Years,Months#,
Months,Inquires FROM #Inquires
WHERE Company = ''Company_Name'')t PIVOT (SUM(Inquires)
FOR Years IN ('+#years+')) AS pvt ORDER BY Company, Months#'
EXECUTE (#query)
I am getting this error while executing this code:
Column name or number of supplied values does not match table definition
This code is running fine in SQL Server 2008, but not in SQL Server 2014.
I'm guessing that you now have more years returned from your pivot than you have in your table.
Try specifying your column names for your insert and in your select.
Good day StackOverflow
The table that I create from my dynamic sql can have any number of columns as it is a pivot table.
-- Pivot the table so we get the UW as columns rather than rows
DECLARE #SQL NVARCHAR(MAX)
SET #SQL = '
SELECT *
FROM #PreProcessed
PIVOT (SUM(Quotes)
FOR [UW] IN (' + #UWColumns + ')
) AS bob'
I run this code to run my dynamic sql.
EXEC sp_executesql #SQL,
N'#UWColumns nvarchar(MAX)',
#UWColumns
My question is, how do I store the resulting table? Especially when I don't know how many columns it will have or even what the columns will be called?
I tried the code below but it doesn't work
INSERT INTO #Temp
EXEC sp_executesql #SQL,
N'#UWColumns nvarchar(MAX)',
#UWColumns
Thanks everyone
SQL Server uses SELECT * INTO ...., as opposed to the CREATE TABLE AS syntax. So you'll need to modify your dynamic sql to:
SELECT * INTO <YOUR TABLE>
FROM #PreProcessed
PIVOT (SUM(Quotes)
FOR [UW] IN (' + #UWColumns + ')
) AS bob'
The only way I could find around this problem was to do all of my calculations in the dynamic sql. Which meant I had to work on two tables.
-- Pivot the table so we get the UW as columns rather than rows
DECLARE #SQL NVARCHAR(MAX)
SET #SQL = '
SELECT * INTO #temp
FROM #PreProcessed
PIVOT (SUM(Quotes)
FOR [UW] IN (' + #UWColumns + ')
) AS bob
SELECT DISTINCT t1.Date, d.Declines AS ''Declines'' , '+#UWColumns+'
FROM #temp AS t1 LEFT OUTER JOIN
#Declines AS d ON t1.DATE = d.DATE
'
PRINT #SQL
EXEC(#SQL)
I've seen this, so I know how to create a pivot table with a dynamically generated set of fields. My problem now is that I'd like to get the results into a temporary table.
I know that in order to get the result set into a temp table from an EXEC statement you need to predefine the temp table. In the case of a dynamically generated pivot table, there is no way to know the fields beforehand.
The only way I can think of to get this type of functionality is to create a permanent table using dynamic SQL. Is there a better way?
Ran in to this issue today, and posted on my blog. Short description of solution, is to create a temporary table with one column, and then ALTER it dynamically using sp_executesql. Then you can insert the results of the dynamic PIVOT into it. Working example below.
CREATE TABLE #Manufacturers
(
ManufacturerID INT PRIMARY KEY,
Name VARCHAR(128)
)
INSERT INTO #Manufacturers (ManufacturerID, Name)
VALUES (1,'Dell')
INSERT INTO #Manufacturers (ManufacturerID, Name)
VALUES (2,'Lenovo')
INSERT INTO #Manufacturers (ManufacturerID, Name)
VALUES (3,'HP')
CREATE TABLE #Years
(YearID INT, Description VARCHAR(128))
GO
INSERT INTO #Years (YearID, Description) VALUES (1, '2014')
INSERT INTO #Years (YearID, Description) VALUES (2, '2015')
GO
CREATE TABLE #Sales
(ManufacturerID INT, YearID INT,Revenue MONEY)
GO
INSERT INTO #Sales (ManufacturerID, YearID, Revenue) VALUES(1,2,59000000000)
INSERT INTO #Sales (ManufacturerID, YearID, Revenue) VALUES(2,2,46000000000)
INSERT INTO #Sales (ManufacturerID, YearID, Revenue) VALUES(3,2,111500000000)
INSERT INTO #Sales (ManufacturerID, YearID, Revenue) VALUES(1,1,55000000000)
INSERT INTO #Sales (ManufacturerID, YearID, Revenue) VALUES(2,1,42000000000)
INSERT INTO #Sales (ManufacturerID, YearID, Revenue) VALUES(3,1,101500000000)
GO
DECLARE #SQL AS NVARCHAR(MAX)
DECLARE #PivotColumnName AS NVARCHAR(MAX)
DECLARE #TempTableColumnName AS NVARCHAR(MAX)
DECLARE #AlterTempTable AS NVARCHAR(MAX)
--get delimited column names for various SQL statements below
SELECT
-- column names for pivot
#PivotColumnName= ISNULL(#PivotColumnName + N',',N'') + QUOTENAME(CONVERT(NVARCHAR(10),YearID)),
-- column names for insert into temp table
#TempTableColumnName = ISNULL(#TempTableColumnName + N',',N'') + QUOTENAME('Y' + CONVERT(NVARCHAR(10),YearID)),
-- column names for alteration of temp table
#AlterTempTable = ISNULL(#AlterTempTable + N',',N'') + QUOTENAME('Y' + CONVERT(NVARCHAR(10),YearID)) + ' MONEY'
FROM (SELECT DISTINCT [YearID] FROM #Sales) AS Sales
CREATE TABLE #Pivot
(
ManufacturerID INT
)
-- Thats it! Because the following step will flesh it out.
SET #SQL = 'ALTER TABLE #Pivot ADD ' + #AlterTempTable
EXEC sp_executesql #SQL
--execute the dynamic PIVOT query into the temp table
SET #SQL = N'
INSERT INTO #Pivot (ManufacturerID, ' + #TempTableColumnName + ')
SELECT ManufacturerID, ' + #PivotColumnName + '
FROM #Sales S
PIVOT(SUM(Revenue)
FOR S.YearID IN (' + #PivotColumnName + ')) AS PivotTable'
EXEC sp_executesql #SQL
SELECT M.Name, P.*
FROM #Manufacturers M
INNER JOIN #Pivot P ON M.ManufacturerID = P.ManufacturerID
you could do this:
-- add 'loopback' linkedserver
if exists (select * from master..sysservers where srvname = 'loopback')
exec sp_dropserver 'loopback'
go
exec sp_addlinkedserver #server = N'loopback',
#srvproduct = N'',
#provider = N'SQLOLEDB',
#datasrc = ##servername
go
declare #myDynamicSQL varchar(max)
select #myDynamicSQL = 'exec sp_who'
exec('
select * into #t from openquery(loopback, ''' + #myDynamicSQL + ''');
select * from #t
')
EDIT: addded dynamic sql to accept params to openquery
Let me try this explanation of select into instead. I'm running SQL Server 2005 as well. Because you have PIVOT tables I'm going to assume the same or 2008.
select
o.*,
OtherField1,
OtherField2
INTO #temp
FROM
OriginalOtherData as ood
PIVOT (
MAX([Value])
FOR Field in (OtherField1, OtherField2)
) as piv
RIGHT OUTER join
Original o on o.OriginalSD = piv.OriginalSD
select * from #temp
Drop table #temp
The only difference between a normal select and a select into is that INTO #table part.
for query (select col1, col2, col3 from tablename
col1 becomes rowlabels
col2 becomes columnheaders
col3 is the dataset
also gets rid of the global table
if OBJECT_ID('tempdb..#3') is not null drop table #3
if OBJECT_ID('tempdb..##3') is not null drop table ##3
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT distinct ',' + QUOTENAME( col2 ) from tablename FOR XML PATH(''), col2).value('.', 'NVARCHAR(MAX)'),1,1,'')
set #query = 'SELECT col1, ' + #cols + ' into ##3 from ( select col1, col2, col3 from tablename ) x pivot ( max(col3)for col2 in (' + #cols + ')) p '
execute(#query)
select * into #3 from ##3 if OBJECT_ID('tempdb..##3') -- is not null drop table ##3