New demand generation from available in the form of buckets - sql

I have a requirement where in there are forecasted values of few offices which are linked to one main office.
For example,office 1,office 2, office 3 are linked to mainoffice.Forecasted values are for entire month.Now I need to use some formula to create demand for mainoffice based on its link offices.
1 2 3 4 5 28 29 30
office1 100 200 300 150 120 100 130 160
office2 200 100 150 200 130 160 120 100
office3 400 350 200 400 260 100 130 200
now main office in the month
required output - ((officetotal1+officetotal2+officetotal3)/30)*5
This same value has to be put in the form of 3 buckets for month
i.e 1st 11th and 21st
1 11 21
mainoffice1 X X X
mainoffice2 Y Y Y
Mapping
office mainoffice
------ ---------
office1 mainoffice1/n
office2 mainoffice1/n
office3 mainoffice2/n

You do this with a join. It is something like:
proc sql;
select o.mainoffice, sum(val1) as val1, sum(val2) as val2, . . .
from forecasts f join
offices o
on f.office = o.office
group by o.mainoffice;
The point is to do a join to get the main office information and then to do an aggregation for the values you want.
EDIT:
Then you just add together the values that you want:
select o.mainoffice,
sum(val1 + val2 + . . . val10 + val11) as val1_11,
. . .
from forecasts f join
offices o
on f.office = o.office
group by o.mainoffice;

Related

Oracle - Getting the rows w/ condition of two columns having minimum values

I am a newbie to PLSQL. I would like to ask for your help.
I have a table below.
Item
Week
Qty
DMD_WK
DMD_QTY
ACC_DMD
WIP
H00978A510
26
300
26
0
0
1
H00978A510
26
300
27
0
0
2
H00978A510
26
300
28
300
300
3
H00978A510
26
300
29
100
400
3
H00978A510
26
300
30
100
500
4
first of all, I want to filter the records that has QTY < ACC_DMD. so the result will be below(I'm okay w/ this part)
Item
Week
Qty
DMD_WK
DMD_QTY
ACC_DMD
WIP
H00978A510
26
300
29
100
400
3
H00978A510
26
300
30
100
500
4
then, I need to get the row having the minimum DMD_WK and also having the minimum WIP grouped by item, week and qty after the filter being applied(Need help on this part)
so that the query will result in this:
Item
Week
Qty
DMD_WK
DMD_QTY
ACC_DMD
WIP
H00978A510
26
300
29
100
400
3
Hoping for your time and help, thanks in advance.
SELECT *
FROM YOURTABLE t
WHERE
DMD_WK = (SELECT MIN(tin.DMD_WK)
FROM YOURTABLE tin
WHERE tin.ITEM = t.ITEM AND tin.QTY < tin.ACC_DMD
GROUP BY tin.ITEM )
AND WIP = (SELECT MIN(tin.WIP)
FROM YOURTABLE tin
WHERE tin.ITEM = t.ITEM AND tin.QTY < tin.ACC_DMD
GROUP BY tin.ITEM )

How can I transfer the data from on column to another based on another column values in SQL

select Products, Fiscal_year, Fiscal_Period, Stock_QTY, DaysRemaining,
(Stock_QTY / DaysRemaining) as QtyforPeriod,
Stock_QTY -(Stock_QTY / DaysRemaining) as LeftforNextmonth
from Stocks
products| Fiscal_yaer| Fiscal_period| Stock_QTY |DaysReamain| QtyforPeriod |LeftforNextMonth
5000 22 1 100 4
6000 22 1 200 4
7000 22 2 300 20
7000 22 3 400 40
8000 23 1 500 60
5000 23 1 600 60
7000 23 2 700 90
8000 23 3 800 100
There is any possibility to write a query if the Fiscal_yae =22 Fiscal_period=4. Subtract StockTY - LeftforNextMonth of period 3 and divided by DaysRemaining.
Like if the Fiscal_yae =22 Fiscal_period=5. Subtract StockTY - LeftforNextMonth of period 4 and divided by days remaining.
Like if the Fiscal_yae =22 Fiscal_period=6. Subtract StockTY ( - ) LeftforNextMonth of period 5 and divided by days remaining.

How to write the query to make report by month in sql

I have the receiving and sending data for whole year. so i want to built the monthly report base on that data with the rule is Fisrt in first out. It means is the first receiving will be sent out first ...
DECLARE #ReceivingTbl AS TABLE(Id INT,ProId int, RecQty INT,ReceivingDate DateTime)
INSERT INTO #ReceivingTbl
VALUES (1,1001,210,'2019-03-12'),
(2,1001,315,'2019-06-15'),
(3,2001,500,'2019-04-01'),
(4,2001,10,'2019-06-15'),
(5,1001,105,'2019-07-10')
DECLARE #SendTbl AS TABLE(Id INT,ProId int, SentQty INT,SendMonth int)
INSERT INTO #SendTbl
VALUES (1,1001,50,3),
(2,1001,100,4),
(3,1001,80,5),
(4,1001,80,6),
(5,2001,200,6)
SELECT * FROM #ReceivingTbl ORDER BY ProId,ReceivingDate
SELECT * FROM #SendTbl ORDER BY ProId,SendMonth
Id ProId RecQty ReceivingDate
1 1001 210 2019-03-12
2 1001 315 2019-06-15
5 1001 105 2019-07-10
3 2001 500 2019-04-01
4 2001 10 2019-06-15
Id ProId SentQty SendMonth
1 1001 50 3
2 1001 100 4
3 1001 80 5
4 1001 80 6
5 2001 200 6
--- And the below is what i want:
Id ProId RecQty ReceivingDate ... Mar Apr May Jun
1 1001 210 2019-03-12 ... 50 100 60 0
2 1001 315 2019-06-15 ... 0 0 20 80
5 1001 105 2019-07-10 ... 0 0 0 0
3 2001 500 2019-04-01 ... 0 0 0 200
4 2001 10 2019-06-15 ... 0 0 0 0
Thanks!
Your question is not clear to me.
If you want to purely use the FIFO approach, therefore ignore any data the table contains, you necessarely need to order by ID, which in your example you are providing, and looks like it is in order of insert.
The first line inserted should be also the first line appearing in the select (FIFO), in order to do so you have to use:
ORDER BY Id ASC
Which will place the lower value of the ID first (1, 2, 3, ...)
To me though, this doesn't make much sense, so pay attention to the meaning o the data you actually have and leverage dates like ReceivingDate, and order by that, maybe even filtering by month of the date, below an example for January data:
WHERE MONTH(ReceivingDate) = 1

How do I change my SQL SELECT GROUP BY query to show me which records are missing a value?

I have a list of codes by area and type. I need to get the unique codes for each type, which I can do with a simple SELECT query with a GROUP BY. I now need to know which area does not have one of the codes. So how do I run a query to group by unique values and tell me how records do not have one of the values?
ID Area Type Code
1 10 A 123
2 10 A 456
3 10 B 789
4 10 B 987
5 10 C 654
6 10 C 321
7 20 A 123
8 20 B 789
9 20 B 987
10 20 C 654
11 20 C 321
12 30 A 137
13 30 A 456
14 30 B 579
15 30 B 789
16 30 B 987
17 30 C 654
18 30 C 321
I can run this query to group them by type and get get the unique codes:
SELECT tblExample.Type, tblExample.Code
FROM tblExample
GROUP BY tblExample.Type, tblExample.Code
This gives me this:
Type Code
A 123
A 137
A 456
B 579
B 789
B 987
C 321
C 654
Now I need to know which areas do not have a given code. For example, Code 123 does not appear for Area 10 and code 137 does not appear for codes 10 and 20. How do I write a query to give me that areas are missing a code? The format of the output doesn't matter, I just need to get the results. I'm thinking the results could be in one column or spread out in multiple columns:
Type Code Missing Areas or Missing1 Missing2
A 123 30 30
A 137 10, 20 10 20
A 456 20 20
B 579 10, 20 10 20
B 789
B 987
C 321
C 654
You can get a list of the missing code/areas by first generating all combinations and then filtering out the ones that exist:
select t.type, c.code
from (select distinct type from tblExample) t cross join
(select distinct code from tblExample) c left join
tblExample e
on t.type = e.type and c.code = e.code
where e.type is null;

How to assign the Parent Group IDs to each record of a hierarchical table in Oracle 11g?

Based on the following sample hierarchical data that exists within the TECH_VALUES table, how can I create a view, say TECH_VALUES_VW that will take this same data but have an additional column, namely GROUP_ID_PARENT that will show the group id where the parent group id is 0 against the row that child belongs to, see new column data sample:
ID GROUP_ID LINK_ID PARENT_GROUP_ID TECH_TYPE GROUP_ID_PARENT
------- ------------- ------------ -------------------- ---------- ---------------
1 100 LETTER_A 0 100
2 200 LETTER_B 0 200
3 300 LETTER_C 0 300
4 400 LETTER_A1 100 A 100
5 500 LETTER_A2 100 A 100
6 600 LETTER_A3 100 A 100
7 700 LETTER_AA1 400 B 100
8 800 LETTER_AAA1 700 C 100
9 900 LETTER_B2 200 B 200
10 1000 LETTER_BB5 900 B 200
12 1200 LETTER_CC1 300 C 300
13 1300 LETTER_CC2 300 C 300
14 1400 LETTER_CC3 300 A 300
15 1500 LETTER_CCC5 1400 A 300
16 1600 LETTER_CCC6 1500 C 300
17 1700 LETTER_BBB8 900 B 200
18 1800 LETTER_B 0 1800
19 1900 LETTER_B2 1800 B 1800
20 2000 LETTER_BB5 1900 B 1800
21 2100 LETTER_BBB8 1900 B 1800
So based on the above, I want to take the table definition:
Table Name: TECH_VALUES:
ID,
GROUP_ID,
LINK_ID
PARENT_GROUP_ID,
TECH_TYPE
and create a new view
View Name: TECH_VALUES_VW:
ID,
GROUP_ID,
LINK_ID
PARENT_GROUP_ID,
TECH_TYPE,
GROUP_ID_PARENT
based on the above sample data from the TECH_VALUES table.
I am looking to create a new query to build this new view which will only use the GROUP_IDs for the PARENT_GROUP_IDs that are 0 for each row.
Updated
Just to make things a whole lot clearer of exactly what I am after is if I take out only the records where the PARENT_GROUP_ID is 0 within the TECH_VALUES table, i.e.
ID GROUP_ID LINK_ID PARENT_GROUP_ID
------- ------------- ------------ --------------------
1 100 LETTER_A 0
2 200 LETTER_B 0
3 300 LETTER_C 0
18 1800 LETTER_B 0
Using just the GROUP_ID values for these 4 records, assign this GROUP_ID to all of the children records for each of these parent link ids as a new column in the TECH_VALUES_VW as well as to the original link ids (where PARENT_GROUP_ID is 0) as shown in the sample data set above.
If I understood your question correctly, then this might be what you're after:
CREATE OR REPLACE VIEW tech_values_vw
AS
SELECT TV.*,
CASE WHEN LEVEL = 1 THEN group_id ELSE connect_by_root(group_id) END AS group_id_parent
FROM tech_values TV
START WITH parent_group_id = 0
CONNECT BY PRIOR group_id = parent_group_id
;