oracle SQL convert some columns to rows [duplicate] - sql

This question already has an answer here:
Oracle 11g - Unpivot
(1 answer)
Closed 5 years ago.
I have a table like below and i am trying to find the best query to convert only the months to rows.
**CODE YEAR JAN FEB MAR**
aa 2017 1 2 3
bb 2017 4 5 6
cc 2017 7 8 9
So that the result is:
**CODE YEAR MONTH value**
aa 2017 JAN 1
aa 2017 FEB 2
aa 2017 MAR 3
bb 2017 JAN 4
bb 2017 FEB 5
bb 2017 MAR 6
cc 2017 JAN 7
cc 2017 FEB 8
cc 2017 MAR 9
Could you please help

Setup table with data:
Select * into #tmpTbl from (
Select 'aa' as Code,2017 as Yr, 1 as Jan,2 as Feb,3 as Mar UNION ALL
Select 'bb' as Code,2017 as Yr, 4 as Jan,5 as Feb,6 as Mar UNION ALL
Select 'cc' as Code,2017 as Yr, 7 as Jan,8 as Feb,9 as Mar) z
Transform query to produce flattened results:
SELECT Code, Yr, CrossApplied.Fld, CrossApplied.Val as Value
FROM #tmpTbl
CROSS APPLY (VALUES (JAN,'JAN'),
(FEB,'FEB'),
(MAR,'MAR'))
CrossApplied (Val,Fld)
The structure of your data might be better reworked to make the data more inline with how you want it represented. This works but its a lot of work around to get there from here.

Related

SQL query to Find highest value in table and sum the corresponding value

I would like to group Highest values in month column group by year and Sum the value column
value
Year
Month
4
2019
10
1
2019
11
5
2019
11
1
2019
11
1
2019
12
8
2019
12
1
2019
12
1
2020
1
10
2020
1
3
2021
1
2
2021
2
11
2021
2
1
2021
2
3
2021
2
2
2021
3
In above table I would like to extract highest value of month group by year
in year 2019 highest month is 12 so there are 3 rows and sum of value column will be 10
The output should be
value
Year
Month
10
2019
12
11
2020
1
2
2021
3
supposing that the table is called "example_table" you can use the following query:
select sum(example_table.value), example_table.year, example_table.month
from example_table
join (
select year, max(month) "month"
from example_table
group by year
) sub on example_table.year = sub.year and example_table.month = sub.month
group by example_table.year, example_table.month
order by example_table.year

Oracle - looping though a list of date ranges with CONNECT BY LEVEL

I am trying to expand upon another article to reach my needs. I am trying to build out a calendar based on our fiscal periods and seem to be creating an infinite loop, or rather one soo large SQL is squashing the query. A procedural solution will not work in the environment that I am trying to build this into, I am only able to use built-in features of the software otherwise I am in breach of my support agreement.
I will break down some of the output so you can see the raw data.
select distinct ap.accounting_year, ap.accounting_period, ap.date_from, ap.date_until
from accounting_period ap
where ap.accounting_period not in (0,13) and ap.accounting_year = :FY
order by ap.accounting_year, ap.accounting_period
This will output the following
2018 1 01-OCT-17 28-OCT-17
2018 2 29-OCT-17 25-NOV-17
2018 3 26-NOV-17 30-DEC-17
2018 4 31-DEC-17 27-JAN-18
2018 5 28-JAN-18 24-FEB-18
2018 6 25-FEB-18 31-MAR-18
2018 7 01-APR-18 28-APR-18
2018 8 29-APR-18 26-MAY-18
2018 9 27-MAY-18 30-JUN-18
2018 10 01-JUL-18 28-JUL-18
2018 11 29-JUL-18 25-AUG-18
2018 12 26-AUG-18 29-SEP-18
Now when I run the following query which I added an additional prompt for the period to limit the above result to 1-row and things work as intended.
WITH
fiscal as (
select distinct ap.accounting_year, ap.accounting_period, ap.date_from, ap.date_until
from accounting_period ap
where ap.accounting_period not in (0,13) and ap.accounting_year = :FY and ap.accounting_period = :FP
order by ap.accounting_year, ap.accounting_period
),
calendar AS (
SELECT f.accounting_year, f.accounting_period, f.date_from + ROWNUM -1 fiscal_day
FROM dual, fiscal f
CONNECT BY LEVEL <= f.date_until - f.date_from + 1
)
select * from calendar;
Output;
2018 9 27-MAY-18
2018 9 28-MAY-18
2018 9 29-MAY-18
2018 9 30-MAY-18
2018 9 31-MAY-18
2018 9 01-JUN-18
2018 9 02-JUN-18
2018 9 03-JUN-18
2018 9 04-JUN-18
2018 9 05-JUN-18
2018 9 06-JUN-18
2018 9 07-JUN-18
2018 9 08-JUN-18
2018 9 09-JUN-18
2018 9 10-JUN-18
2018 9 11-JUN-18
2018 9 12-JUN-18
2018 9 13-JUN-18
2018 9 14-JUN-18
2018 9 15-JUN-18
2018 9 16-JUN-18
2018 9 17-JUN-18
2018 9 18-JUN-18
2018 9 19-JUN-18
2018 9 20-JUN-18
2018 9 21-JUN-18
2018 9 22-JUN-18
2018 9 23-JUN-18
2018 9 24-JUN-18
2018 9 25-JUN-18
2018 9 26-JUN-18
2018 9 27-JUN-18
2018 9 28-JUN-18
2018 9 29-JUN-18
2018 9 30-JUN-18
In the end, I would like to be able to run this to output the records for all 12 periods and create a fiscal year calendar since this view does not exist in the current database.
I can post my entire query if requested, but this is where I am stuck, I was able to build the rest of my script by adding prompts to select the fiscal year and period in the WITH clause, but when I implement this into the end report I will have to create a view where the prompt will not be available within the WITH.
Thank You
If I understand well your need, this could be what you need:
select accounting_year, accounting_period, date_from, date_until, date_from + level -1 as calendare_date
from yourResult
connect by date_from + level -1 <= date_until
and prior accounting_year = accounting_year
and prior accounting_period = accounting_period
and prior sys_guid() is not null
order by accounting_year, accounting_period
For example, with a reduced set of data:
with yourResult(accounting_year, accounting_period, date_from, date_until) as (
select 2018, 1 , to_date('01-OCT-17', 'dd-mon-yy'), to_date('05-OCT-17', 'dd-mon-yy') from dual union all
select 2018, 2 , to_date('06-OCT-17', 'dd-mon-yy'), to_date('07-OCT-17', 'dd-mon-yy') from dual union all
select 2018, 3 , to_date('08-OCT-17', 'dd-mon-yy'), to_date('10-oct-17', 'dd-mon-yy') from dual
)
select accounting_year, accounting_period, date_from, date_until,
date_from + level -1 as calendare_date
from yourResult
connect by date_from + level -1 <= date_until
and prior accounting_year = accounting_year
and prior accounting_period = accounting_period
and prior sys_guid() is not null
order by accounting_year, accounting_period;
you have:
ACCOUNTING_YEAR ACCOUNTING_PERIOD DATE_FROM DATE_UNTI CALENDARE
--------------- ----------------- --------- --------- ---------
2018 1 01-OCT-17 05-OCT-17 01-OCT-17
2018 1 01-OCT-17 05-OCT-17 02-OCT-17
2018 1 01-OCT-17 05-OCT-17 03-OCT-17
2018 1 01-OCT-17 05-OCT-17 04-OCT-17
2018 1 01-OCT-17 05-OCT-17 05-OCT-17
2018 2 06-OCT-17 07-OCT-17 06-OCT-17
2018 2 06-OCT-17 07-OCT-17 07-OCT-17
2018 3 08-OCT-17 10-OCT-17 08-OCT-17
2018 3 08-OCT-17 10-OCT-17 09-OCT-17
2018 3 08-OCT-17 10-OCT-17 10-OCT-17

Add column value to next column in SQL

My sql table is
Week Year Applications
1 2017 0
2 2017 10
3 2017 20
4 2017 50
5 2017 0
1 2018 10
2 2018 0
3 2018 40
4 2018 50
5 2018 10
And I want SQL query which give below output
Week Year Applications
1 2017 0
2 2017 10
3 2017 30
4 2017 80
5 2017 80
1 2018 10
2 2018 10
3 2018 50
4 2018 100
5 2018 110
Can anyone help me to write below query?
You could use SUM() OVER to get cumulative sum:
SELECT *, SUM(Applications) OVER(PARTITION BY Year ORDER BY Week)
FROM tab
It looks like you want a cumulative sum:
select week, year,
sum(applications) over (partition by year order by week) as cumulative_applications
from t;

Merging old table with new table with different structure

I am using SQL Server 2012. I have two tables which I need to 'merge'. The two tables are called tblOld and tblNew.
tblOld has data from say 2012 to 2013
tblNew has data from 2013 onwards and has a different structure
The dates do not overlap between the tables.
Simple example of the tables:
Old table
t_date region sub_region sales
------------------------------------------
1 Jan 2012 US QR 2
1 Jan 2012 US NT 3
1 Jan 2012 EU QR 5
2 Jan 2012 US QR 4
2 Jan 2012 US NT 6
2 Jan 2012 EU QR 10
...
31 Dec 2013 US QR 8
31 Dec 2013 US NT 9
31 Dec 2013 EU QR 15
New table
t_date region sales
-----------------------------
1 Jan 2014 US 20
1 Jan 2014 EU 50
2 Jan 2014 US 40
2 Jan 2014 EU 100
...
31 Dec 2014 US 80
31 Dec 2014 EU 150
Result I'm looking for:
t_date US QR US NT EU
-------------------------------------
1 Jan 2012 2 3 5
2 Jan 2012 4 6 10
...
31 Dec 2013 8 9 15
1 Jan 2014 20 50
2 Jan 2014 40 100
...
31 Dec 2014 80 150
So I'm trying to create a query which will give me the results above although I'm not sure how to do this or if it can be done?
SELECT t_date,
SUM(CASE WHEN region='US' AND (sub_region='QR' OR sub_region IS NULL) THEN sales ELSE 0 END) 'US QR',
SUM(CASE WHEN region='US' AND sub_region='NT' THEN sales ELSE 0 END) 'US NT',
SUM(CASE WHEN region='EU' THEN sales ELSE 0 END) 'EU'
FROM (
SELECT t_date
,region
,sub_region
,sales
FROM tblOLD
UNION ALL
SELECT t_date
,region
,NULL
,sales
FROM tblNEW
) t
GROUP BY t_date
You are looking for a UNION of the two tables:
SELECT t_date
,region
,sales
,sub_region
FROM tblOLD
UNION ALL
SELECT t_date
,region
,NULL
,sales
FROM tblNEW

TSQL query to filter configuration dates list

How should i form a query if i wanted dates/records from the below table such that Year is greater than or equals 2012 and Month is greater than September.
This query does not work it brings Months 2012 (7,8, 9,10,11,12) , 2013(1 upto 12) which is not right because i wanted to see 2012(9,10,11,12) 2013( 1 upto 12). It is including 7 and 8 th month of 2012 Year
select * from ConfigurationDate
where Year >= 2012 OR ( Year = 2012 AND Month >= 9 )
Order By Year,Month ASC
Table Schema
DateId INT Auto Inc
Year INT
Month INT
Dummy Data
DateId Year Month
1 2012 7
2 2012 8
3 2012 9
4 2012 10
5 2012 11
6 2012 12
7 2013 1
8 2013 2
9 2013 3
10 2013 4
11 2013 5
12 2013 6
13 2013 7
14 2013 8
15 2013 9
16 2013 10
Actually thinking of it, i don't need to include the 2012 date in First where condition again since it is covered by second condition. So the answer is below
select * from ConfigurationDate
where Year > 2012 OR ( Year = 2012 AND Month >= 9 )
Order By Year,Month ASC