Convert rows to columns using pivot - sql

I try to convert this procedure to PIVOT, but I can't. Does anyone have a solution to help?
I have a table has ItemID, StoreID,Stock
I want to convert it to ItemID, Store1,Store2,Store3...,Stock
sum the stock according to itemID and StoreID then inserts the result as a row.
Many thanks
CREATE table #test222
([Id] int,[ItemID] INT, [storeid] int, [stock] decimal(18,2)
);
INSERT INTO #test222
([Id],[ItemID], [storeid], [stock])
VALUES
(1, 1, 3,10),
(2, 1,1, 20),
(3, 1,1, 30),
(4, 2,1, 40),
(5, 2,2,50),
(6, 2,2,60),
(7, 3,2,70),
(8, 4,2,80),
(9, 4,2,90),
(10, 5,2,100);
select * from #test222;
select ItemID, store1,store2,storeid3,storeid4,storeid5,storeid6,storeid7,storeid8,storeid9,storeid10 stock
from
(
select ItemID, storeid, stock
from #test222
) d
pivot
(
max(stock)
for storeid in (1,2,3,4,5,6,7,8,9,10)
) piv;
Give error:
Msg 102 Level 15 State 1 Line 9
Incorrect syntax near '1'.

Here is a simple PIVOT. Just remember to "feed" your pivot with just only the required columns
Example
Select *
From (
Select ItemID
,Col = 'store'+left(storeid,10)
,val = stock
From #test222
) src
Pivot ( max(val) for Col in ( store1,store2,storeid3,storeid4,storeid5,storeid6,storeid7,storeid8,storeid9,storeid10 ) ) src
Results

Related

SQL Pivot Columns with prefixes

New to SQL, struggling to fully understand the pivot clause. I have four fields (state, season, rain, snow) and am trying to pivot so that I have 5 fields (state, summer_rain, summer_snow, winter_rain, winter_snow). I'm not sure how to pivot two fields so that they are prefixed with another if that makes sense. Reprex below.
What I have now
What I'm after
My code (receiving an error when aggregating snow & rain within pivot clause):
DECLARE #myTable AS TABLE([state] VARCHAR(20), [season] VARCHAR(20), [rain] int, [snow] int)
INSERT INTO #myTable VALUES ('AL', 'summer', 1, 1)
INSERT INTO #myTable VALUES ('AK', 'summer', 3, 3)
INSERT INTO #myTable VALUES ('AZ', 'summer', 0, 1)
INSERT INTO #myTable VALUES ('AL', 'winter', 5, 4)
INSERT INTO #myTable VALUES ('AK', 'winter', 2, 2)
INSERT INTO #myTable VALUES ('AZ', 'winter', 1, 1)
INSERT INTO #myTable VALUES ('AL', 'summer', 6, 4)
INSERT INTO #myTable VALUES ('AK', 'summer', 3, 0)
INSERT INTO #myTable VALUES ('AZ', 'summer', 5, 1)
SELECT [state], [year], [month], [day]
FROM
(
SELECT * FROM #myTable
) t
PIVOT
(
sum([rain]), sum([snow]) FOR [season] IN ([summer], [winter])
) AS pvt
PIVOTS are great, but Conditional Aggregations offer a bit more flexibility and often more performant.
PIVOT
Select *
From (
SELECT State
,B.*
FROM #myTable
Cross Apply (values (concat(season,'_rain'),rain)
,(concat(season,'_snow'),snow)
) B(Item,Value)
) src
Pivot ( sum(value) for Item in ([summer_rain],[summer_snow],[winter_rain],[winter_snow]) ) pvt
Conditional Aggregation
Select State
,[summer_rain] = sum(case when season='summer' then rain end)
,[summer_snow] = sum(case when season='summer' then snow end)
,[winter_rain] = sum(case when season='winter' then rain end)
,[winter_snow] = sum(case when season='winter' then snow end)
From #myTable
Group By State

SQL Query to get the value of a product given a date

I have a table which gives the rate of a product on a particular date, #tableA.
create table #tableA
(
Id int not null,
ValueDate date,
Price decimal(9,2)
)
insert into #tableA (Id, ValueDate, Price)
values
(1, '2020-08-01', 100),
(1, '2020-08-05', 110),
(1, '2020-08-07', 50)
My other table has the id and the date the product is active.
create table #tableB
(
Id int not null,
Dates date
)
insert into #tableB (Id, Dates)
values
(1, '2020-08-01'),
(1, '2020-08-02'),
(1, '2020-08-03'),
(1, '2020-08-04'),
(1, '2020-08-05'),
(1, '2020-08-06'),
(1, '2020-08-07'),
(1, '2020-08-04')
I cannot find an efficient query where my resulting table gives the rate of the product on a given date.
I am expecting this result.
Id Dates ValueDate Price
-------------------------------------
1, '2020-08-01', '2020-08-01', 100
1, '2020-08-02', '2020-08-01', 100
1, '2020-08-03', '2020-08-01', 100
1, '2020-08-04', '2020-08-01', 100
1, '2020-08-05', '2020-08-05', 110
1, '2020-08-06', '2020-08-05', 110
1, '2020-08-07', '2020-08-07', 50
Something like this:
SELECT DISTINCT B.[id]
,B.[Dates]
,DS.*
FROM #tableB B
CROSS APPLY
(
SELECT TOP 1 *
FROM #tableA A
WHERE B.[Id] = A.[Id]
AND B.[Dates] >= A.[ValueDate]
AND A.[Price] IS NOT NULL
ORDER BY A.[ValueDate] DESC
) DS;
or this:
WITH DataSource AS
(
SELECT DISTINCT B.[ID]
,B.[Dates]
,A.[ValueDate]
,A.[Price]
,SUM(IIF(A.[ID] IS NOT NULL, 1, 0)) OVER (ORDER BY B.[Dates]) AS [GroupID]
FROM #tableB B
LEFT JOIN #tableA A
ON B.[Id] = A.[Id]
AND B.[Dates] = A.[ValueDate]
AND A.[Price] IS NOT NULL
)
SELECT [ID]
,[Dates]
,MAX([ValueDate]) OVER (PARTITION BY [GroupID]) AS [ValueDate]
,MAX([Price]) OVER (PARTITION BY [GroupID]) AS [Price]
FROM DataSource;

SQL Recursive query on Parent > Child Table [duplicate]

I have a simple categories table as with the following columns:
Id
Name
ParentId
So, an infinite amount of Categories can be the child of a category. Take for example the following hierarchy:
I want, in a simple query that returns the category "Business Laptops" to also return a column with all it's parents, comma separator or something:
Or take the following example:
Recursive cte to the rescue....
Create and populate sample table (Please save us this step in your future questions):
DECLARE #T as table
(
id int,
name varchar(100),
parent_id int
)
INSERT INTO #T VALUES
(1, 'A', NULL),
(2, 'A.1', 1),
(3, 'A.2', 1),
(4, 'A.1.1', 2),
(5, 'B', NULL),
(6, 'B.1', 5),
(7, 'B.1.1', 6),
(8, 'B.2', 5),
(9, 'A.1.1.1', 4),
(10, 'A.1.1.2', 4)
The cte:
;WITH CTE AS
(
SELECT id, name, name as path, parent_id
FROM #T
WHERE parent_id IS NULL
UNION ALL
SELECT t.id, t.name, cast(cte.path +','+ t.name as varchar(100)), t.parent_id
FROM #T t
INNER JOIN CTE ON t.parent_id = CTE.id
)
The query:
SELECT id, name, path
FROM CTE
Results:
id name path
1 A A
5 B B
6 B.1 B,B.1
8 B.2 B,B.2
7 B.1.1 B,B.1,B.1.1
2 A.1 A,A.1
3 A.2 A,A.2
4 A.1.1 A,A.1,A.1.1
9 A.1.1.1 A,A.1,A.1.1,A.1.1.1
10 A.1.1.2 A,A.1,A.1.1,A.1.1.2
See online demo on rextester

Apply PIVOT operator multiple times on same column

I have the next table structure:
And need the data in the next format:
But the result is the following:
My code:
SELECT * FROM (
SELECT
record,
field AS real_field,
real_value,
field AS string_field,
string_value
FROM my_table ) AS source
PIVOT ( MAX(string_value) FOR string_field IN ([1],[2],[3],[4]) ) AS string_pivot
PIVOT ( MAX(real_value) FOR real_field IN ([5],[6]) ) AS real_pivot;
Any ideas? Thank you.
You could simply use coalesce, no?
DECLARE #test TABLE(record INT,
field INT,
real_value DECIMAL NULL,
string_value VARCHAR(10) NULL);
INSERT INTO #test(record, field, real_value, string_value)
VALUES(1, 1, NULL, 'A'),
(1, 2, NULL, 'B'),
(1, 3, NULL, 'C'),
(1, 4, NULL, 'D'),
(1, 5, 1.0, NULL),
(1, 6, 2.0, NULL);
SELECT *
FROM(
SELECT record, field, COALESCE(CONVERT(VARCHAR(10), real_value, 0), string_value) AS value
FROM #test
) AS source
PIVOT(MAX(value)
FOR field IN([1], [2], [3], [4], [5], [6])
) AS real_pivot;
Well, it was actually simpler than I thought:
SELECT record, MAX([1]), MAX([2]), MAX([3]), MAX([4]), MAX([5]), MAX([6]) FROM ( SELECT record, field AS real_field, real_value, field AS string_field, string_value FROM my_table ) AS source
PIVOT ( MAX(string_value) FOR string_field IN ([1],[2],[3],[4]) ) AS string_pivot
PIVOT ( MAX(real_value) FOR real_field IN ([5],[6]) ) AS real_pivot
GROUP BY record;

SQL Server recursive self join

I have a simple categories table as with the following columns:
Id
Name
ParentId
So, an infinite amount of Categories can be the child of a category. Take for example the following hierarchy:
I want, in a simple query that returns the category "Business Laptops" to also return a column with all it's parents, comma separator or something:
Or take the following example:
Recursive cte to the rescue....
Create and populate sample table (Please save us this step in your future questions):
DECLARE #T as table
(
id int,
name varchar(100),
parent_id int
)
INSERT INTO #T VALUES
(1, 'A', NULL),
(2, 'A.1', 1),
(3, 'A.2', 1),
(4, 'A.1.1', 2),
(5, 'B', NULL),
(6, 'B.1', 5),
(7, 'B.1.1', 6),
(8, 'B.2', 5),
(9, 'A.1.1.1', 4),
(10, 'A.1.1.2', 4)
The cte:
;WITH CTE AS
(
SELECT id, name, name as path, parent_id
FROM #T
WHERE parent_id IS NULL
UNION ALL
SELECT t.id, t.name, cast(cte.path +','+ t.name as varchar(100)), t.parent_id
FROM #T t
INNER JOIN CTE ON t.parent_id = CTE.id
)
The query:
SELECT id, name, path
FROM CTE
Results:
id name path
1 A A
5 B B
6 B.1 B,B.1
8 B.2 B,B.2
7 B.1.1 B,B.1,B.1.1
2 A.1 A,A.1
3 A.2 A,A.2
4 A.1.1 A,A.1,A.1.1
9 A.1.1.1 A,A.1,A.1.1,A.1.1.1
10 A.1.1.2 A,A.1,A.1.1,A.1.1.2
See online demo on rextester