I have a table
City Region Zone Passcode SureveyBy SureveyDone SureveyExpiry
Noida Sector 62 East 1 ABC Y NULL
Noida Sector 2 West 1 XYZ N 6/10/2016
Delhi CP Cnt 10 ABC N 10/10/2018
Delhi KB West 11 RST Y NULL
I need result in this format
Final Result
DECLARE #col NVARCHAR(max),#sql NVARCHAR(max)
SELECT #col=ISNULL(#col+',[','[')+t.SureveyBy+']' FROM dbo.myTable AS t GROUP BY t.SureveyBy
PRINT #col
SET #sql='
SELECT * FROM dbo.myTable
PIVOT(MAX(SureveyDone) FOR SureveyBy IN ('+#col+')) p'
EXEC(#sql)
Related
I have 4 tables A, B, C and X.
X table :
Icid Trade_Id Counter_Party
---------------------------------
1 101 HDFC1
2 102 HDFC1
3 103 HDFC2
4 104 HDFC2
5 105 HDFC2
6 106 HDFC3
7 107 HDFC4
8 108 HDFC4
9 109 HDFC5
10 110 HDFC5
A table :
Icid Trade_Id Name
----------------------------------
1 110 HDFC Bank Pvt Ltd
2 105 HDFC Bank Pvt Ltd
3 101 HDFC Bank Pvt Ltd
4 102 HDFC Bank Pvt Ltd
B table:
Icid Trade_Id Name
----------------------------------------
1 103 HSBC Pvt Ltd
2 104 HSBC Pvt Ltd
3 106 HSBC Pvt Ltd
C table :
Icid Trade_Id Name
--------------------------------------
1 107 HK Pvt Ltd
2 108 HK Pvt Ltd
3 109 HK Pvt Ltd
A, B, C table like this and I have created another table and store tables name as below.
Findtbl table:
Icid Table_name
------------------
2 A
3 B
4 C
I need to table X Trade_ID find to tables A, B and C. If found in table A, then print location column INDIA, if found in table B then print location column USA, and if found in table C, then location column is Hongkong in #Temp table location, Trade_Id, Name columns:
#temp table :
Icid location Trade_Id Name
I tried this:
Declare #Fst_value nvarchar(100)
Declare #Counter INT
Declare #tablename nvarchar(20)
Declare #sql nvarchar(max)
Declare #isvalue int
Declare #loop int = 1
Declare #sqlsecond nvarchar(max)
Declare #sqlthird nvarchar(max)
SET #Fst_value = '104'
SET #Counter = (Select COUNT(Icid) From Findtbl)
WHILE #Loop < = #Counter
BEGIN
SET #tablename = (SELECT Table_name
FROM Findtbl
WHERE Icid = #Loop)
SET #sql = 'Select #isvalue = Icid,#sqlsecond = Trade_Id,#sqlthird = Name From '+#tablename+' Where Trade_Id = '+#Fst_value+''
Execute sp_executesql #sql,N'#isvalue int OUTPUT,#sqlsecond nvarchar OUTPUT,#sqlthird nvarchar OUTPUT',#isvalue = #isvalue OUT,#sqlsecond = #sqlsecond OUT,#sqlthird = #sqlthird OUT
if(#isvalue <> 0)
begin
Select #sql
break
end
SET #isvalue = 0
SET #Loop = #Loop + 1
END
This code is contained in a stored procedure.
I'll give it a shot, though you probably need to spend some time re-stating your question.
I'm going to have to ignore the procedural code, and use set-based code.
insert into #temp (Icid, location, Trade_Id, Name)
select case
when A.Trade_ID is not null then A.Icid
when B.Trade_ID is not null then B.Icid
when C.Trade_ID is not null then C.Icid
end
,case
when A.Trade_ID is not null then 'INDIA'
when B.Trade_ID is not null then 'USA'
when C.Trade_ID is not null then 'Hongkong'
end
,case
when A.Trade_ID is not null then A.Trade_ID
when B.Trade_ID is not null then B.Trade_ID
when C.Trade_ID is not null then C.Trade_ID
end
,case
when A.Trade_ID is not null then A.Name
when B.Trade_ID is not null then B.Name
when C.Trade_ID is not null then C.Name
end
from X
left outer join A on X.Trade_ID on A.Trade_ID
left outer join B on X.Trade_ID on B.Trade_ID
left outer join C on X.Trade_ID on C.Trade_ID
I understand how to use PIVOT to rotate rows into columns but I have a unique scenario where rows also have to be grouped. The source data is from a NoSQL database schema (un-relational). Here is an example of the source data:
ID case_id field_id sequence_number textvalue
1 12897 25 100 AAAAA
2 12897 50 100 BBBBB
3 12897 75 100 CCCCC
4 13587 25 200 DDDDD
5 13587 50 200 EEEEE
6 13587 75 200 FFFFF
7 13587 100 200 GGGGG
The result I need is:
case_id value_field_id_25 value_field_id_50 value_field_id_75 value_field_id_100
12897 AAAAA BBBBB CCCCC
13587 DDDDD EEEEE FFFFF GGGGG
So, what I need is a row of related records grouped by sequence_number. The number of rows with the same sequence_number is dynamic (it varies).
Any ideas?
Declare #SQL varchar(max) = Stuff((Select ',' + QuoteName('value_field_id_'+cast(field_id as varchar(25)))
From (Select Distinct Top 100 Percent field_id
From YourTable
Order by 1) A
For XML Path('')),1,1,'')
Select #SQL = '
Select [case_id],' + #SQL + '
From (
Select sequence_number
,case_id
,ColName = ''value_field_id_''+cast(field_id as varchar(25))
,Value = textvalue
From YourTable A
) A
Pivot (max([Value]) For [ColName] in (' + #SQL + ') ) p'
Exec(#SQL);
Returns
Please help me with this. I have the data as this:
ID Name TotalCost IsCorporate
---- ---------------- ---------- -----------
1 Wash, Dry & Fold 175.00 1
2 Hand Wash and Fold 275.00 0
3 Pressing Only 25.00 0
4 Hand Wash and Fold 205.00 1
5 Pressing Only 100.00 0
If IsCorporate = 0 then the Total Cost will align to the Corporate column like this:
ID Wash, Dry & Fold Hand Wash and Fold Pressing Only Corporate
---- ---------------- ----------------- -------------- -----------
1 175.00
2 275.00
3 25.00
4 205.00
5 100.00
This is my stored procedure code:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[ReportSales]
AS
BEGIN
SELECT
IDJO, ISCORP, ST.[Wash, Dry & Fold], ST.[Pressing Only],
ST.[Dry Clean], ST.[Hand Wash and Fold], ST.[Wash, Dry & Press],
ST.[Stain Removal], ST.[Hand Wash and Press], CORPORATE
FROM
(SELECT
JO.Id AS IDJO, CI.Active AS ISCORP, ST.Name,
ISNULL(JO.TotalCost, 0) AS TC
FROM
JobOrders JO
INNER JOIN
ClientInformations CI ON JO.ClientId = CI.Id
INNER JOIN
JobOrderDetails JOD ON JO.Id = JOD.JOrderId
INNER JOIN
ServiceTypes ST ON JOD.ServiceId = ST.Id
INNER JOIN
Payments P ON JO.Id = P.JobOrderId
INNER JOIN
PaymentStatus PS ON JO.PaymentStatusId = PS.Id
INNER JOIN
Status S ON JO.StatusId = s.Id) AS J
PIVOT
(SUM(TC) for Name IN ([Wash, Dry & Fold], [Pressing Only], [Dry
Clean], [Hand Wash and Fold], [Wash, Dry & Press], [Stain Removal],
[Hand Wash and Press], [Corporate]) ) AS ST
END
Use dynamic column collection to select PIVOT Data, because it gives you any new column value added in table, suppose after 2-3 days if new Name say for XYZ added in your table even that it show your new column in PIVOT result:
CREATE TABLE ReportSales
(
ID INT,
Name VARCHAR(50),
TotalCost DECIMAL(10,2),
IsCorporate BIT
)
INSERT INTO ReportSales VALUES(1,'Wash, Dry & Fold',175.00,1)
,(2,'Hand Wash and Fold',275.00,0)
,(3,'Pressing Only',25.00,0)
,(4,'Hand Wash and Fold',205.00,1)
,(5,'Pressing Only',100.00,0)
DECLARE #Name AS NVARCHAR(MAX),#Query AS NVARCHAR(MAX);
SET #Name = STUFF((SELECT distinct ',' + QUOTENAME(Name)
FROM ReportSales c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
SET #Query =
'IF OBJECT_ID(''tempdb..#tblRS'') IS NOT NULL
DROP TABLE #tblRS
SELECT
ID,
RS.Name,
TotalCost,
ISCorporate,
CASE RS.IsCorporate WHEN 1 THEN 0 ELSE RS.TotalCost END AS Corporate
INTO #tblRS
FROM ReportSales RS
SELECT ID, ' + #Name + ',Corporate from
(
SELECT
*,
CASE ISCorporate WHEN 1 THEN TotalCost ELSE 0 END AS NewTotalCost
FROM #tblRS
) x
pivot
(
SUM(TotalCost)
FOR Name in (' + #Name + ')
) p '
PRINT(#query)
EXECUTE(#query)
#Name : It will give you your column list on which you wants to apply SUM
The system we are using allows a data entry form to be created from multiple user defined fields to satisfy information required on a particular group of different "ORDES". The fields are then stored in a database as such from what is entered:
GUID OrderGUID UserDataCode Value
1 100 OrderName Breakfast
2 100 OrderDesc Food you eat before Lunch
3 100 CerealYN Y
4 100 ToastYN Y
5 100 ToastDesc White Bread
6 100 PaperYN Y
7 100 PaperDesc The Newsroom
8 101 OrderName Lunch
9 101 OrderDesc Food you eat before Dinner
10 101 CerealYN N
11 101 ToastYN Y
12 101 ToastDesc Brown Bread
13 101 PaperYN Y
14 101 PaperDesc The MiddayNews
(etc)
(in fact this is an Enterprise Hospital software but I have used simpler examples here)
I would like using SQL to return this table PIVOTed like below
OrderGUID OrderName OrderDESC CerealYN ToastYN ToastDesc ....
101 Breakfast Food you.. Y Y White Bread ....
102 Lunch Food you.. N Y Brown Bread ....
I wrote the following SQL based on examples found on the net:
DECLARE #DynamicPivotQuery AS NVARCHAR(MAX)
DECLARE #ColumnName AS NVARCHAR(MAX)
--Get distinct values of the PIVOT Column
SELECT #ColumnName= ISNULL(#ColumnName + ',','')
+ QUOTENAME([UserDataCode])
FROM (
SELECT
[UserDataCode]
FROM
[XXX].[dbo].[CV3OrderUserData]
WHERE OrderGUID = 3000680
) AS Codes;
--Prepare the PIVOT query using the dynamic
SET #DynamicPivotQuery = N'SELECT OrderGUID, ' + #ColumnName + '
FROM
[XXX].[dbo].[CV3OrderUserData]
PIVOT(Max(Value)
FOR UserDataCode IN (' + #ColumnName + ')) AS PVTTable'
--Execute the Dynamic Pivot Query
--SELECT #DynamicPivotQuery
EXEC sp_executesql #DynamicPivotQuery
However while it does the pivot as requested.. and puts the values in the correct new "dynamic" columns, if returns a row for each OrderGUID + Value,
ie:
OrderGUID OrderName OrderDesc CerealYN ToastYN
100 Breakfast null null null ...
100 null Food you.. null null ...
101 null null Y null ...
etc.etc
What am i doing wrong :( ?
The problem in your query is the pivot source query has GUID column which makes the pivot operator to consider GUID column.
To get the expected output you need to remove GUID column from the pivot source query.
Here is a static version you can convert it to dynamic version as you already did.
select * from
(
SELECT OrderGUID,UserDataCode,Value
FROM
tst) A
PIVOT(Max(Value)
FOR UserDataCode IN ([OrderName],[OrderDesc],
[CerealYN],[ToastYN],
[ToastDesc],[PaperYN],
[PaperDesc])) AS PVTTable
SQLFIDDLE DEMO
I have a PIVOT situation.
Source table columns:
Title Description Datetime RecordsCount
A California 2015-07-08 10:44:39.040 5
A California 2015-07-08 12:44:39.040 6
A California 2015-05-08 15:44:39.040 3
B Florida 2015-07-08 16:44:39.040 2
B Florida 2015-05-08 19:44:39.040 4
Now I need this pivoted as
2015-07-08 2015-05-08
Title Description
A California 11 3
B Florida 2 4
if we have two record counts on same dates (no matter of time) then sum them, else display in different column.
Trying to write something like this, but it throws errors.
Select * from #DataQualTest
PIVOT (SUM(RecordCount) FOR DateTime IN (Select Datetime from #DataQualTest) )
AS Pivot_Table
Please help me out with this.
Thanks
Not exactly the word for word solution but this should give you a direction.
create table #tmp
(
country varchar(max)
, date1 datetime
, record int
)
insert into #tmp values ('California', '2010-01-01', 2)
insert into #tmp values ('California', '2010-01-01', 5)
insert into #tmp values ('California', '2012-01-01', 1)
insert into #tmp values ('Florida', '2010-01-01', 3)
insert into #tmp values ('Florida', '2010-01-01', 5)
select * from #tmp
pivot (sum(record) for date1 in ([2010-01-01], [2012-01-01])) as avg
output
country 2010-01-01 2012-01-01
California 7 1
Florida 8 NULL
If you want to be more flexible, you need some pre-processing to get from full timestamps to days (in order for later on the PIVOT's grouping to actually have the anticipated effect):
CREATE VIEW DataQualTestView AS
SELECT
title
, description
, DATEFROMPARTS (DATEPART(yyyy, date_time),
DATEPART(mm, date_time),
DATEPART(dd, date_time)) AS day_from_date_time
, recordsCount
FROM DataQualTest
;
From there you could continue:
DECLARE #query AS NVARCHAR(MAX)
DECLARE #columns AS NVARCHAR(MAX)
SELECT #columns = ISNULL(#columns + ',' , '')
+ QUOTENAME(day_from_date_time)
FROM (SELECT DISTINCT
day_from_date_time
FROM DataQualTestView) AS TheDays
SET #query =
N'SELECT
title
, description
, ' + #columns + '
FROM DataQualTestView
PIVOT(SUM(recordsCount)
FOR day_from_date_time IN (' + #columns + ')) AS Pivoted'
EXEC SP_EXECUTESQL #query
GO
... and would get:
| title | description | 2015-05-08 | 2015-07-08 |
|-------|-------------|------------|------------|
| A | California | 3 | 11 |
| B | Florida | 4 | 2 |
See it in action: SQL Fiddle.
Please comment, if and as this requires adjustment / further detail.