in sql how to arrange rows of data into colum using Pivot - sql

Here i have a simple table i want to display all rows respected that year display in single column
Year Month Amt
1999 Jan 520
1999 Feb 100
199 Mar 200
2000 Jan 500
2000 Feb 200
I want to display these table as
Year Jan Feb Mar
1999 520 100 200
2000 500 200 null
I had Written query as invoice its my table name
select
[Jan] as January,
[Feb] as Feburary,
[March] as Feburary,
from(
select Year,month,amount from invoice)x
PIVOT(
sum(amount)
for month in([jan],[Feb],[March])
)p

Please Try This Query
create table #Invoice
(
ID int identity(1,1),
Year varchar(4),
Month varchar(3),
Amount int
)
insert into #Invoice (Year, Month, Amount) values ('1999','Jan',520),('1999','Feb',100),('1999','Mar',200),
('2000','Jan',500),('2000','Feb',200)
select Year, [Jan], [Feb],[Mar],[Grand Total]
from (
select Year, Month, Amount
from #Invoice
Union all
select Year, 'Grand Total', SUM(Amount)
from #Invoice
group by year
)dd
pivot (
sum(Amount) for Month in ([Jan], [Feb],[Mar],[Grand Total])
) piv
drop table #Invoice

You can achieve it using CTE. You can't GROUP BY YEAR within the PIVOT table operator, the PIVOT operator infers the grouped columns automatically. This seems to work
WITH Pivoted
AS
(
SELECT *
FROM table1
PIVOT
(
sum([Amt]) FOR [month] IN ( [jan],[Feb],[Mar])
) AS p
)
SELECT
Year,
sum([Jan]) as January,
sum([Feb]) as Feburary,
sum([Mar]) as March
FROM Pivoted
GROUP BY Year;
REXTESTER DEMO

Related

Subtract value from group of same table

Year Month Code Value
2021 January 201 100.00
2021 February 201 250.00
2021 January 202 300.00
2021 February 202 200.00
2021 March 201 50.00
2021 March 202 150.00
Need to subtract code 201 from 202 , grouping both code by month.
Output :
Year Month Value
2021 january 200
2021 february -50
2021 March 100
I was trying to get desired output but its not working..
SELECT Code,Value
,
(
SELECT sum(Value) as Value
FROM [TestD]
Where Code = '202'
GROUP BY Code
)-(
SELECT sum(Value) as Value
FROM [TestD]
where Code = '201'
GROUP BY Code
) AS item_total
FROM [TestD] group by Code,Value
You can use a case expression inside sum(...), with group by Year, Month:
select Year,
Month,
sum(case when Code = '201' then -Value when Code = '202' then Value end) as Value
from TestD
group by Year, Month
Fiddle
You can try this provided only 2 values are going to be subtracted
declare #tbl table (year int, [month] varchar(50),code int, [value] int)
insert into #tbl values(2021, 'January', 201, 100.00),(2021, 'Feb', 201, 250.00)
,(2021, 'January', 202, 300.00),(2021, 'Feb', 202, 200.00)
select year,[month],[value], row_number()over(partition by [month] order by [value] desc) rownum
into #temp
from #tbl
select year,
month
,case when rownum = 1 then value else (
(select value from #temp t1 where t1.[month] = t.[month] and t1.rownum = 1) -
value) end as diff
from #temp t
where t.rownum = 2
order by month desc
drop table #temp

How to get every nth row value in sql

I have a select statement in sql:
SELECT DISTINCT [Year] FROM [data_list] ORDER BY [YEAR] ASC;
Result:
Year
----
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
I want list of year in 3 increments. For example:
Year
----
2019
2022
2025
2028
One way to do it is to use a common table expression with dense_rank, and then filter the results by it.
First, create and populate sample table (Please save us this step in your future questions):
DECLARE #T AS TABLE
(
[Year] int
)
INSERT INTO #T ([Year]) VALUES
(2019),
(2019),
(2019),
(2020),
(2020),
(2021),
(2022),
(2022),
(2023),
(2024),
(2024),
(2025),
(2025),
(2026),
(2027),
(2027),
(2028);
The cte and query:
WITH CTE AS
(
SELECT [Year],
DENSE_RANK() OVER(ORDER BY [Year]) - 1 As dr
FROM #T
)
SELECT DISTINCT [Year]
FROM CTE
WHERE dr % 3 = 0
ORDER BY [Year]
results:
Year
2019
2022
2025
2028
You can use ROW_NUMBER:
SELECT [Year]
FROM (
SELECT [Year], ROW_NUMBER() OVER (ORDER BY [Year] ASC) rn
FROM table_name
GROUP BY [YEAR]
) t WHERE (t.rn - 1) % 3 = 0
demo on dbfiddle.uk
Try it,
;WITH CTEs AS
(
SELECT *,(CASE WHEN [Year] %3 =0 THEN [Year] END) AS [Year] FROM yourTable
)
SELECT * FROM CTEs WHERE [Year] IS NOT NULL

My Sql PIVOT Query Is Not Working As Intended

I'm using the following SQL query to return a table with 4 columns Year, Month, Quantity Sold, Stock_Code,
SELECT yr, mon, sum(Quantity) as Quantity, STOCK_CODE
FROM [All Stock Purchased]
group by yr, mon, stock_code
order by yr, mon, stock_code
This is an example of some of the data BUT I have about 3000 Stock_Codes and approx 40 x yr/mon combinations.
yr mon Quantity STOCK_CODE
2015 4 42 100105
2015 4 220 100135
2015 4 1 100237
2015 4 2 100252
2015 4 1 100277
I want to pivot this into a table which has a row for each SKU and columns for every Year/Month combination.
I have never used Pivot before so have done some research and have created a SQL query that I believe should work.
select * from
(SELECT yr,
mon, Quantity,
STOCK_CODE
FROM [All Stock Purchased]) AS BaseData
pivot (
sum(Quantity)
For Stock_Code
in ([4 2015],[5 2015] ...........
) as PivotTable
This query returns a table with Yr as col1, Mon as col2 and then 4 2015 etc as subsequent columns. Whereas I want col1 to be Stock_Code and col2 to show the quantity of that stock code sold in 4 2015.
Would really like to understand what is wrong with my code above please.
The following query using dynamic PIVOT should do what you want:
CREATE TABLE #temp (Yr INT,Mnt INT,Quantity INT, Stock_Code INT)
INSERT INTO #temp VALUES
(2015,4,42,100105),
(2015,4,100,100105),
(2015,5,220,100135),
(2015,4,1,100237),
(2015,4,2,100252),
(2015,7,1,100277)
DECLARE #pvt NVARCHAR(MAX) = '';
SET #pvt = STUFF(
(SELECT DISTINCT N', ' + QUOTENAME(CONVERT(VARCHAR(10),Mnt) +' '+ CONVERT(VARCHAR(10),Yr)) FROM #temp FOR XML PATH('')),1,2,N'');
EXEC (N'
SELECT pvt.* FROM (
SELECT Stock_Code
,CONVERT(VARCHAR(10),Mnt) +'' ''+ CONVERT(VARCHAR(10),Yr) AS [Tag]
,Quantity
FROM #temp )a
PIVOT (SUM(Quantity) FOR [Tag] IN ('+#pvt+')) pvt');
Result is as below,
Stock_Code 4 2015 5 2015 7 2015
100105 142 NULL NULL
100135 NULL 220 NULL
100237 1 NULL NULL
100252 2 NULL NULL
100277 NULL NULL 1
You can achieve this without using pivoting.
SELECT P.`STOCK_CODE`,
SUM(
CASE
WHEN P.`yr`=2015 AND P.`mon` = '1'
THEN P.`Quantity`
ELSE 0
END
) AS '1 2015',
SUM(
CASE
WHEN P.`yr`=2015 AND P.`mon` = '2'
THEN P.`Quantity`
ELSE 0
END
) AS '2 2015',
SUM(
CASE
WHEN P.`yr`=2015 AND P.`mon` = '3'
THEN P.`Quantity`
ELSE 0
END
) AS '3 2015',
FROM [All Stock Purchased] P
GROUP BY P.`STOCK_CODE`;

Summing together values from the same table in different databases

I have a table on each database for a region of a company with the number of sales per month like so:
Region1.dbo.SalesPerMonth Region2.dbo.SalesPerMonth
ID Month Sales ID Month Sales
1 Jan 23 1 Jan 21
2 Feb 19 2 Feb 15
3 Jan 31 3 Jan 25
... ... ... ... ... ...
I am looking to write a query to join these tables into one table that shows the sales for the entire company per month, so it has the total sales from all regions added together:
AllRegions
ID Month Sales
1 Jan 44
2 Feb 34
3 Jan 56
... ... ...
I am however new to SQL and am not sure how to go about doing so. Any help or advice on how to write the query would be greatly appreciated.
Union together the two tables, and then aggregate by ID and Month to generate the sum of sales.
SELECT
ID, Month, SUM(Sales) AS Sales
FROM
(
SELECT ID, Month, Sales
FROM Region1.dbo.SalesPerMonth
UNION ALL
SELECT ID, Month, Sales
FROM Region2.dbo.SalesPerMonth
) t
GROUP BY
ID, Month
ORDER BY
ID;
Demo here:
Rextester
Try this:
WITH DataSource AS
(
SELECT *
FROM Region1.dbo.SalesPerMonth
UNION ALL
SELECT *
FROM Region2.dbo.SalesPerMonth
)
SELECT [id]
,[Month]
,SUM(Sales) AS Sales
FROM DataSource
GROUP BY [id]
,[Month]

How to sum two values of same month and year in sql server

state month ID sales
-------------------------------------
FL 05/18/2015 0001 12,000
FL 05/19/2015 0001 6,000
FL 05/20/2015 0001 3,000
FL 05/21/2015 0001 6,000
FL 06/01/2016 0001 4,000
TX 06/02/2016 0050 1,000
In the above table month column having same month but with different date. My question is how to add/sum of sales column having same month with different dates?
try this way
select datepart(year,month) as year ,datepart(month,month) as month, sum(sales)
from tablename
group by datepart(year,month) ,datepart(month,month)
Use a simple aggregation on the month column. You can use the DATENAME function to extract the month given a date.
SELECT YEAR([month]), DATENAME(MONTH, [month]) AS Month,
SUM(sales)
FROM mytable
GROUP BY YEAR([month]), DATENAME(MONTH, [month]);
first see this question on how to convert the month column (assuming it's a string/varchar) to a date.
Next make a sum() of the sales column grouping by the month and year part of the date.
Are you saying for you want the totals for January .. December irrespective of the year?
If yes then you could do a simple agrregate and group by DATEPART(month, theDate)
EG
SELECT STATE, DATEPART(month, [month]), SUM(sales)
FROM yourTable
GROUP BY
STATE, DATEPART(month, [month])
By using the below query you can get the result as month, year wise:
SELECT MONTH([Month]) [Month], YEAR([Month]) [Year], SUM(Sales) TotalSales
FROM TestTable
GROUP BY MONTH([Month]), YEAR([Month])
ORDER BY MONTH([Month]), YEAR([Month])
Actual execution with given sample data:
DECLARE #TestTable TABLE ([State] VARCHAR (20), [Month] DATE, ID VARCHAR(5), Sales INT);
INSERT INTO #TestTable ([State], [Month], ID, Sales)
VALUES
('FL', '05/18/2015', '0001', 12000),
('FL', '05/19/2015', '0001', 6000),
('FL', '05/20/2015', '0001', 3000),
('FL', '05/21/2015', '0001', 6000),
('FL', '06/01/2016', '0001', 4000),
('TX', '06/02/2016', '0050', 1000),
('TX', '05/02/2016', '0050', 1000)
SELECT MONTH([Month]) [Month], YEAR([Month]) [Year], SUM(Sales) TotalSales
FROM #TestTable
GROUP BY MONTH([Month]), YEAR([Month])
ORDER BY MONTH([Month]), YEAR([Month])
Result:
Month Year TotalSales
5 2015 27000
5 2016 1000
6 2016 5000
Below query might help you :-
declare #test111 table
(name varchar(20) NOT NULL,
month date NOT NULL,
col1 int NOT NULL,
sales int NOT NULL)
Insert into #test111
values('FL','05/18/2015',0001,12000),
('FL','05/19/2015',0001,6000),
('FL','05/20/2015',0001,3000),
('FL','05/21/2015',0001,6000),
('FL','06/01/2016',0001,4000),
('TX','06/02/2016',0050,1000)
select month,sum(sales) over (partition by datepart(mm,month)) Sales
from #test111
Output :
month Sales
2015-05-18 27000
2015-05-19 27000
2015-05-20 27000
2015-05-21 27000
2016-06-01 5000
2016-06-02 5000