SQL Server : aggregating multiple measures columns into 1 column - sql

I'm a SQL novice and tried my best to search for this topic before asking.
I have data in this format:
I need in this format:
I realize this is something probably very easy, but any help would be greatly appreciated.
Thanks!

You can use APPLY if you are working with SQL Server :
SELECT t.year, tt.Months, tt.Amount
FROM TABLE t CROSS APPLY
( VALUES (1, 'January', [Month1]),
(2, 'February', [Month2]),
. . .
) tt(seq, Months, Amount)
ORDER BY tt.seq, t.year;

You can try this on SQL SERVER:
CREATE TABLE TestPvt (Year varchar(32), January int, february int,
March int);
GO
INSERT INTO TestPvt VALUES ('Actual 2019',700,220,456);
INSERT INTO TestPvt VALUES ('Budget 2019',200,752,500);
SELECT Year, Month, Amount
FROM
(SELECT Year, January, february, March
FROM TestPvt) p
UNPIVOT
(Amount FOR Month IN
(January, february, March)
)AS unpvt;
The result is:
Year Month Amount
Actual 2019 January 700
Actual 2019 february 220
Actual 2019 March 456
Budget 2019 January 200
Budget 2019 february 752
Budget 2019 March 500

You could try:
Taking the columns you provide i made this SQL, i hope this helps!
Just change the table for the original
SELECT Year,
case when Month = 'Month1' then 'January'
when Month = 'Month2' then 'February'
when Month = 'Month3' then 'March'
else '' end as Month,
Amount
FROM
(SELECT Year, Month1, Month2, Month3
FROM [dbo].[ExampleMonths]) tb1
UNPIVOT
(Amount for Month IN
(tb1.Month1, tb1.Month2, tb1.Month3)
) AS uNp

Related

Customers that stopped ordering monthly-SQL

I am trying to write an SQL query that shows STORES that stopped ordering in a month. That would be STORES that have orders the month before but no orders that month. For example STORES that have orders in January but do Not have orders in Febuary (these would be the STORES that stopped ordering for Febuary). I want to do this for every month (grouped) for a given date range - #datefrom-#dateto
I have one table with an INVOICE#,STORE# and a DATE column
I guess distinct STORE would be in there somewhere.
You can try something like this, break them into two select statements and left outer join them.
select table1.stores from (select * from table where date = 'January') as table1
left outer join (select * from table where date = 'Feburary') as table2
on table1.invoice= table2.invoice
this will return the unique results in January that does not match the results from February
ps. that was not an exact sql statement, just an idea
I have an example that might be close to what you desire. You may have to tweak it to your convenience and desired performance - http://sqlfiddle.com/#!3/231c4/15
create table test (
invoice int identity,
store int,
dt date
);
-- let's add some data to show that
-- store 1 ordered in Jan, Feb and Mar
-- store 2 ordered in Jan (missed Feb and Mar)
-- store 3 ordered in Jan and Mar (missed Feb)
insert into test (store, dt) values
(1, '2015-01-01'),(1, '2015-02-01'),(1, '2015-03-01'),
(2, '2015-01-01'),
(3, '2015-01-01'), (3, '2015-03-01');
Query
-----
with
months as (select distinct year(dt) as yr, month(dt) as mth from test),
stores as (select distinct store from test),
months_stores as (select * from months cross join stores)
select *
from months_stores ms
left join test t
on t.store = ms.store
and year(t.dt) = ms.yr
and month(t.dt) = ms.mth
where
(ms.yr = 2015 and ms.mth between 1 and 3)
and t.invoice is null
Result:
yr mth store ...other columns
2015 2 2
2015 2 3
2015 3 2
The results show us that store 2 missed orders in months Feb and Mar
and store 3 missed an order in Feb

Show Query Results in Month/Year Order

I have a query that sales and it shows the month and year (field names are salemonth & saleyear) of the sale. Example return-set would be
January 2014
February 2014
March 2014
December 2014
January 2015
Now obviously I can't set it that way in my straight query as if I try to order by salemonth ASC it woudl show December, February, january, january, March. or even if I order by year ASC it still would not show in the actual calendar month order. How can I sort this result set to show in the order of an actual calendar?
One caveat their may be 0 sales for the month (november for example) I would still want this month/year shown in the query but have a 0 shown. Is this achievable?
A quick idea and fix (not the prettiest of solutions):
SELECT *, CAST(([Month] + ' 1,' + [Year]) AS Datetime) AS OrderDate FROM [TABLE] ORDER BY OrderDate
..or if you prefer to hide the sorting column:
SELECT * FROM [TABLE] ORDER BY CAST(([Month] + ' 1,' + [Year]) AS Datetime)
This is assuming the values are stored as some type of varchar/string, otherwise you'd obviously need to cast a few more bits.

Case statement bucketing in Sybase Sql

I have a data set which looks like this:
month year total_sales
01 2014 4567889
02 2014 5635627
03 2014 997673
04 2014 2134566
05 2014 2666477
My goal is to create a YTD function on the above dataset.
Eg: If I want the 01 month data to display, it should give the total sales for 01 month. If i want the 02 month to display, it should give me the total sales for 01 + 02 month combined and so on for the other months.
The query i wrote goes as follows:
select year, case when month in ('01') then 'JAN'
when month in ('01','02') then 'FEB'
-
-
-
when month in ('01','02','03','04','05') then 'MAY'
end as bucket, sum(total_sales) from <table_name>
group by year, case when month in ('01') then 'JAN'
when month in ('01','02') then 'FEB'
-
-
-
when month in ('01','02','03','04','05') then 'MAY'
end
The result set it fetches, doesn't add up the total sales as a YTD function but instead shows the total sales for that particular month only.
I can create the Pivot table view for the required data set but that is not how i need it because i need to build reports on the data set.
Can someone help me with the concept if i am missing something?
Thanks in advance.
Perhaps a correlated subquery would help:
select t.*,
(select sum(total_sales)
from table t2
where t2.year = t.year and
t2.month <= t.month
) as YTD
from table t;
Here is another solution:
WITH months AS (
SELECT month, year
FROM <table_name>
)
SELECT m.month, m.year, SUM(t.total_sales)
FROM months m JOIN <table_name> t ON t.year=m.year AND t.month<=m.month
GROUP BY m.year, m.month
ORDER BY m.year, m.month;

SQL Month Year datatypes

Its really frustrating whenever I have to work with date/ datetime datatypes and SQL doesn't provide a good and easy way to work with it.
Currently I have this table RecordsDaily with a column Date with datatype date. I want to convert the Date column to month and take only distinct month values AND then sort according to month. Below is the query.
select distinct(CAST(DATEPART(year,Date) as varchar(10)) + ' ' + datename(MONTH,Date)) Month
from P98.dbo.RecordsDaily
where Date >= '2013/12/1'
order by Month
Obviously since I have made it varchar it doesn't consider it as date datatype and sorts it alphabetically as below.
Month
2013 December
2014 April
2014 February
2014 January
2014 March
2014 May
Any help to make it sort as per calendar.
UPDATE
Please note the output should be with Month and Year
Please try:
select Month from(
select distinct(CAST(DATEPART(year,Date) as varchar(10)) + ' ' + datename(MONTH,Date)) Month
,year(Date) yr, month(Date) mn
from P98.dbo.RecordsDaily
where Date >= '2013/12/1'
)x
order by yr, mn
try this !
select * from table order by cast(('01'+id) as datetime)asc
-- id is your column_name

SQL Query Problem

When I am doing SQL Query on the database then all the months that are there in database and all the values corresponding to that particular month will be summed up in the Amount Column.
Suppose this is a table
Month Category Amount Year
January Rent 12 2011
March Food 13 2011
January Gas 14 2011
May Enter 15 2011
March General 16 2011
So I written the query to sum all the values of a particular month by using this:-
"SELECT Month, SUM(Amount) AS OrderTotal FROM budget1 WHERE year="2011" GROUP BY month "
So I got the result as this:-
Month Amount
January 26
March 29
May 15
But I want is that it should show all the months from January to December and Value of 0 infront of those month which are not there in the database like this for above example.
Month Amount
January 26
February 0
March 29
April 0
May 15
June 0
July 0
August 0
September 0
October 0
November 0
December 0
Any help will be appreciated..!!
Create a table with all months Jan-Dec, call it Months. Just a single column with the names or add an extra integer for sort order (I usually call this the ordinal column), as follows:
create table months (
month varchar(20),
ordinal
);
insert into months values ('January', 1);
insert into months values ('February', 2);
insert into months values ('March', 3);
...
insert into months values ('December', 12);
The specific syntax may depend upon your database platform. Then, depending upon your database:
SELECT months.Month, SUM(Amount) AS OrderTotal
FROM months
left join budget1
on months.month = budget1.Month
WHERE year="2011" or year is null
GROUP BY months.month, months.ordinal
ORDER by month.ordinal
You'll need to convert SUM(Amount) to 0 when null. The specific function or approach to do this depends upon your database platform, or you can just do it in the code that is interpreting the results.
Build a month table, with your months and the sort order. Then left join your month column to the month column in your data table. That will get you the zeros.
So your table will look like
Month Sort
======================
January 1
February 2
March 3
etc.
You can create the table by using Create Table, following by Insert Scripts
CREATE TABLE #months (month VARCHAR(50), sort INT);
INSERT INTO #months VALUES ('January', 1);
INSERT INTO #months VALUES ('February', 2);
etc.
Then
SELECT m.Month, SUM(Amount) AS OrderTotal
FROM #months m LEFT OUTER JOIN budget1 on m.Month = budget1.Month
WHERE year=2011
GROUP BY m.Month
ORDER BY m.Sort