SQL Server Sort fixed number of rows/columns horizontally - sql

I'm trying use PIVOT in a SQL Server stored procedure to take the following data:
ID Rank
203081 1.1
200761 3.9
202687 5.3
203135 5.0
203090 3.3
and return the ID's sorted horizontally. The ranking goes from 1 to 6 with each rank having tenths in between. Example 1.0, 1.1, 1.2, 1.3, ... 1.9, 2.0
The ID's need to be sorted in order by rank.
The result should return something like the following:
(if additional columns needed for aggregation that is fine as well.)
[1] ,[2] ,[3] ,[4] ,[5]
202687,203135,200761,203090,203081
Using above data the ID's would be sorted by rank as 5.3->5.0->3.9->3.3->1.1
In the end I need to take the results and insert them into another table with the ID's sorted horizontally.
I can't get the PIVOT to work correctly. I'm sure it is something obvious I'm not seeing.
If there is a better/faster way to achieve what is needed I would like to know what that solution would be as well.

It sounds like you just need to use row_number() to get the ordering correct and then PIVOT the data on that row number.
If you have a limited number values then you can use:
select [1], [2], [3], [4], [5]
from
(
select id,
row_number() over(order by [rank] desc) seq
from yourtable
) d
pivot
(
max(id)
for seq in ([1], [2], [3], [4], [5])
) piv;
See SQL Fiddle with Demo
Or if you are going to have an unknown number, you will use dynamic SQL:
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(row_number() over(order by [rank] desc))
from yourtable
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT ' + #cols + '
from
(
select id,
row_number() over(order by [rank] desc) seq
from yourtable
) x
pivot
(
max(id)
for seq in (' + #cols + ')
) p '
execute sp_executesql #query;
See SQL Fiddle with Demo. These give a result:
| 1 | 2 | 3 | 4 | 5 |
|--------|--------|--------|--------|--------|
| 202687 | 203135 | 200761 | 203090 | 203081 |

Related

SQL Server Query for Many to Many Relationship - how to query?

This is an update to my previous question : Many to many relationship
The previous solution works fine, but now I want tgo improve the results a little bit. I´d like to have all the wavelength values in one row.
So instead of the following result :
DateTimeID Wavelength SensorID
11435 1581,665 334
11435 1515,166 334
11435 1518,286 335
I'd like to have something similar to this:
DateTimeID Wavelength1 Wavelength2 SensorID
11435 1581,665 1515,166 334
11435 1518,286 335
You could use the following which applies a row_number() to the records:
select DateTimeID,
[1] as Wavelength1,
[2] as Wavelength2,
SensorId
from
(
select [DateTimeID], [Wavelength], [SensorID],
row_number() over(partition by DateTimeID, SensorId
order by DateTimeID) rn
from yourtable
) src
pivot
(
max(Wavelength)
for rn in ([1], [2])
) piv
See SQL Fiddle with Demo.
If you will have an unknown number of wavelength values, then you can use dynamic SQL to generate this:
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT distinct ',' + QUOTENAME('Wavelength'+cast(rn as varchar(50)))
from
(
select row_number() over(partition by DateTimeID, SensorId
order by DateTimeID) rn
from yourtable
) src
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT DateTimeID,' + #cols + ', SensorId from
(
select [DateTimeID], [Wavelength], [SensorID],
''Wavelength''+cast(row_number() over(partition by DateTimeID, SensorId
order by DateTimeID) as varchar(50)) rn
from yourtable
) x
pivot
(
max(Wavelength)
for rn in (' + #cols + ')
) p '
execute(#query)
See SQL Fiddle with Demo

Pivot Query - SQL Server 2005

I have the following query in SQL Server 2005 that fetches the result that is mentioned below it.
select Distinct(date),id,
sum(convert(float,Gross)),
count(*) as no from Daily
group by date,id
order by date desc
Date id Gross Count
2012-11-25 00:00:00.000 Client id1 1232.6140752 12
2012-11-25 00:00:00.000 Client id2 1183.75621528 88
2012-11-26 00:00:00.000 Client id3 4561.459086 67
2012-11-26 00:00:00.000 Client id4 6781.15660608 440
Now how do I get the result in the following format. This looks like a pivot query is reqd please help
id Date1 Date2 Date3 Date4 Date5 Date6 Date7
Client id1 Gross
Client id2 Gross
Client id3 Gross
There are two ways that you can PIVOT, either a static version where you hard-code all of the date values or a dynamic version which will generate the list of dates at run-time.
Static Version:
If you had a limited number of dates your query will be similar to this.
select id, [yourDate1], [yourDate2], [yourDate3]
from
(
select date, id, cast(gross as float) as gross
from Daily
) src
pivot
(
sum(gross)
for date in ([yourDate1], [yourDate2], [yourDate3])
) piv;
See SQL Fiddle with Demo
Dynamic Version:
This version generates dynamic SQL to get the list of dates at run-time. Your code will be similar to this:
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(date)
from Daily
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT id, ' + #cols + ' from
(
select date, id, cast(gross as float) as gross
from Daily
) src
pivot
(
sum(gross)
for date in (' + #cols + ')
) p '
execute(#query)
See SQL Fiddle with Demo
WITH a AS
(
SELECT [Id], [Gross]
, [DateRank] = DENSE_RANK() OVER (ORDER BY [Date])
FROM [Daily]
)
SELECT *
FROM a PIVOT
(
SUM([Gross])
FOR [DateRank] IN ([1], [2], [3], [4], [5], [6], [7])
) b

SQL rotate rows to columns...dynamic number of rows [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
SQL Server dynamic PIVOT query?
I have a dataset that has the below structure.
CREATE TABLE #TempTable
(
Measure_ID INT,
measurement DECIMAL(18, 4)
)
INSERT INTO #TempTable
VALUES
(1,2.3)
,(1,3.4)
,(1,3.3)
,(2,3)
,(2,2.3)
,(2,4.0)
,(2,4.5)
I need to produce output that will look like this.
1,2.3,3.4,3.3
2,3,2.3,4.0,4.5
Basically its a pivot on Measure_ID. Unfortunately, there can be an unlimited number of measure_id's. So Pivot is out.
I'm hoping to avoid CURSORS, but will if that turns out to be the best approach.
If you have an unknown number of values, then you can use a PIVOT with dynamic SQL:
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT distinct ','
+ QUOTENAME('Measurement_' + cast(rn as varchar(10)))
from temptable
cross apply
(
select row_number() over(partition by measure_id order by measurement) rn
from temptable
) x
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT measure_id, ' + #cols + ' from
(
select measure_id, measurement,
''Measurement_''
+ cast(row_number() over(partition by measure_id order by measurement) as varchar(10)) val
from temptable
) x
pivot
(
max(measurement)
for val in (' + #cols + ')
) p '
execute(#query)
See SQL Fiddle With Demo
If you have a known number of values, then you can hard-code the values, similar to this:
SELECT measure_id, [Measurement_1], [Measurement_2],
[Measurement_3], [Measurement_4]
from
(
select measure_id, measurement,
'Measurement_'
+ cast(row_number() over(partition by measure_id order by measurement) as varchar(10)) val
from temptable
) x
pivot
(
max(measurement)
for val in ([Measurement_1], [Measurement_2],
[Measurement_3], [Measurement_4])
) p
See SQL Fiddle With Demo
Both queries will produce the same results:
MEASURE_ID | MEASUREMENT_1 | MEASUREMENT_2 | MEASUREMENT_3 | MEASUREMENT_4
==========================================================================
1 | 2.3 | 3.3 | 3.4 | (null)
2 | 2.3 | 3 | 4 | 4.5

T-SQL Group Rows Into Columns

How can I group an (unknown) number of rows into a single row where the set columns determine the grouping?
For example, shift
Ref Name Link
==============================
1 John L1
1 John L2
1 John L8
2 Steve L1
2 Steve L234
Into
Ref Name ... ... ...
==========================================
1 John L1 L2 L8
2 Steve L1 L234 NULL
Thanks for any help
You might pivot the table using row_number() as a source of column names:
select *
from
(
select ref,
name,
link,
row_number() over (partition by ref, name order by link) rn
from table1
) s
pivot (min (link) for rn in ([1], [2], [3], [4])) pvt
Simply extend the list of numbers if you have more rows.
Live test is # Sql Fiddle.
If the number of different Links is unkown this needs to be done dynamically. I think this will work as required:
DECLARE #SQL NVARCHAR(MAX) = ''
SELECT #SQL = #SQL + ',' + QUOTENAME(Rownumber)
FROM ( SELECT DISTINCT ROW_NUMBER() OVER(PARTITION BY Ref, Name ORDER BY Link) [RowNumber]
FROM yourTable
) d
SET #SQL = 'SELECT *
FROM ( SELECT Ref,
name,
Link,
ROW_NUMBER() OVER(PARTITION BY Ref, Name ORDER BY Link) [RowNumber]
FROM yourTable
) data
PIVOT
( MAX(Link)
FOR RowNumber IN (' + STUFF(#SQL, 1, 1, '') + ')
) pvt'
EXECUTE SP_EXECUTESQL #SQL
It is a slight varation of the usual PIVOT function because normally link would be in the column header. It basically determines the number of columns required (i.e. the maximum distinct values for Link per ref/Name) then Pivots the values into these columns.

display rows as column

I want to display rows as column in SQL Server.
My table looks like this:
images_id item_id images_name
-------------------------------
1 1 image1.jpg
2 1 image2.jpg
3 1 image3.jpg
4 2 image4.jpg
5 2 image5.jpg
6 2 image6.jpg
I'd like this output:
images_id item_id image1 image2 image3
------------------------------------------------------
1 1 image1.jpg image2.jpg image3.jpg
2 2 image4.jpg image5.jpg image6.jpg
Here is an image link.
Is this possible or not? item_id must be dynamically changeable (it is not stable).
Cross Tabs and Pivots, Part 1 – Converting Rows to Columns
Cross Tabs and Pivots, Part 2 - Dynamic Cross Tabs
Pivot table for Microsoft SQL Server
This isn't possible without using dynamic SQL. PIVOT requires you to specify the columns still.
Let me know if dynamic SQL is acceptable and I'll spin you an example.
Here is how you can use Dynamic SQL for this:
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
SET #cols = STUFF((SELECT distinct ',' + QUOTENAME('image' + cast(row_number() over(partition by itemid order by imageid) as varchar(5)))
FROM test c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT itemid, ' + #cols + ' from
(
select itemid, imagename,
''image'' + cast(row_number() over(partition by itemid order by imageid) as varchar(5)) col
from test
) x
pivot
(
min(imagename)
for col in (' + #cols + ')
) p '
execute(#query)
See SQL Fiddle with Demo