sum tabel based on certain content - sql

select
om.orderno,
od.product,
od.preorderqty,
(od.preorderqty * od.nto) as preordernet
from OrderMaster om
join OrderDetail od on od.orderid = om.id
and ((od.prodcode like '100-%') or (od.prodcode like '200-%'))
order by om.orderno,sod.prodcode
Current result:
ORDERNO PRODUCT PREORDERQTY PREORDERNET
1000 100-A 2 200
1000 100-B 2 300
1000 100-C 1 450
2000 100-A 3 300
2000 100-B 1 150
2000 200-A 2 900
3000 200-A 1 450
I would need help getting a script that:
Sums the orders based on specific content
Orders can contain products beginning with 300- etc.
Expected result:
ORDERNO PRODUCT PREORDERQTY PREORDERNET ORDERNET
1000 100-A 2 200 950
1000 100-B 2 300 950
1000 100-C 1 450 950
2000 100-A 3 300 1350
2000 100-B 1 150 1350
2000 200-A 2 900 1350
3000 200-A 1 450 450

As I understood from the expected output ,use sum as window function to get it,
select om.orderno
,od.product
,od.preorderqty
,(od.preorderqty * od.nto) as preordernet
,sum(od.preorderqty * od.nto) over (partition by om.orderno) as ordernet
from OrderMaster om
join OrderDetail od
on od.orderid = om.id
and ((od.prodcode like '100-%')
or (od.prodcode like '200-%'))
order by om.orderno,sod.prodcode

Related

Cumulative over table rows with condition Oracle PL/SQL

I have two tables:
Employees:
employee_id field max_amount
3 a 3000
4 a 3000
1 a 1600
2 a 500
4 b 4000
2 b 4000
3 b 1700
ordered by employee, field, amount desc.
Amounts (pol, premia,field):
pol premia field **assign_to_employee**
11 900 a 3
44 1000 a 3
55 1400 a 4
77 500 a 3
88 1300 a 1
22 800 b 4
33 3900 b 2
66 1300 b 4
Assign Stats Table:
employee_id field max_amount true_amount remain
3 a 3000 2400 600
4 a 3000 1400 1600
1 a 1600 1300 300
2 a 500 0 500
4 b 4000 2100 1900
2 b 4000 3900 100
3 b 1700 0 1700
The output : assign_to_employee field (merged to amounts table).
Algoritem wise : The method is to assign pol's to employees until the premia needs to be added to the cumulative_sum is bigger then the max amount per employee listed in the employees table. You always start with the employess with most max amount until you cannot add any other pols to the employee.
I start with the employees with the grater max_amount per field.
I keep doing this until no pols remains to be assign.
Can you help me solve this?
Thank you.

Sum whole column plus a single row of another column and display in a third column

here is my problem i do have a query the returns to me this table
select * from basic_table;
|----network----|--- previa ----|--- month---|--- organic_value----|---financial_value-----|
Rental 1 1 1000 1250
Rental 1 3 3750 3750
Service 2 1 2000 2200
Maintance 1 2 350 500
what i need is to sum all the organic_value where the previa is the same + financial_value of each month
so the final table would be
|----network----|--- previa ----|--- month---|--- organic_value----|---financial_value-----| ---NEW_COLUMN--|
Rental 1 1 1000 1250 (1k + 3,75+0,35k) = 5100 + 1,25k = 6350
Rental 1 3 3750 3750 (5100) + 3,75k = 8850
Service 2 1 2000 2200 2000 + 2200 = 4200
Maintance 1 2 350 500 (5100 + 500) =5600
any tips how to tackle this problem?
That's a window sum:
select t.*,
financial_value + sum(organic_value) over(partition by previa) as new_column
from mytable t

SQL oracle SUM function with conditions

I have a table that looks like this
TIMECODE UNIT_CODE Department Account AMOUNT
20194 10 1000 1000 100
20194 10 2354 1100 150
20194 10 1000 1000 200
20194 10 2354 1000 100
20194 20 500 1000 250
20194 20 500 1100 200
How I need the results to be is like this
TIMECODE UNIT_CODE Department 1000 1100
20194 10 1000 300 NULL
20194 10 2354 100 150
20194 20 500 250 200
hopefully that gives you a better image, but basically I would need to do a SUM depending on the distinct value of the other columns. The accounts that were previously in rows would be changed into columns.
any ideas or help with this would be greatly appreciated
Try the following, here is the demo.
select
TIMECODE,
UNIT_CODE,
Department,
sum(case when Account = 1000 then AMOUNT end) as "1000",
sum(case when Account = 1100 then AMOUNT end) as "1100"
from myTable
group by
TIMECODE,
UNIT_CODE,
Department
Output:
---------------------------------------------------
| TIMECODE UNIT_CODE DEPARTMENT 1000 1100 |
---------------------------------------------------
| 20194 20 500 250 200 |
| 20194 10 1000 300 null|
| 20194 10 2354 100 150 |
---------------------------------------------------

SQL oracle - Delete Duplicate Records and update records in other table

Requirement - Delete Duplicate records e.g. from 2 tables and update the records in the other tables.
Input
Table1 Dim_Ctry
PK_Key1 Country
100 Argentina
200 ARGENTINA
300 India
400 INDIA
Table2 Dim_Geo
PK_Key2 Geo
500 Globe
600 GLOBE
700 Market
800 MARKET
900 Unique
Table Fact1
PK_Key15 FK_KEY1 FK_KEY2
1 100 500
2 200 600
3 300 800
4 400 900
Table Fact2
PK_Key16 FK_KEY1 FK_KEY2
5 100 500
6 200 600
7 200 700
8 300 800
output
Table1 Dim_Ctry
PK_Key1 Country
100 Argentina
300 India
Table2 Dim_Geo
PK_Key2 Geo
500 Globe
700 Market
900 Unique
Table Fact1
PK_Key15 FK_KEY1 FK_KEY2
1 100 500
2 100 500
3 300 800
4 300 800
Table Fact2
PK_Key16 FK_KEY1 FK_KEY2 comment
5 100 500
6 100 500
7 100 700
7 300 800
8 1000 2000 no record in dim table just retain
You will need several steps.
Step 1 update related tables
Update all FK_KEY to the min value.
UPDATE Fact1 f1
SET
FK_KEY1 = (SELECT MIN(PK_Key1)
FROM Dim_Ctry dc1
WHERE UPPER(dc1.Country) = (SELECT UPPER(dc2.Country)
FROM Dim_Ctry dc2
WHERE dc2.PK_Key1 = f1.FK_KEY1)
),
FK_KEY2 = (SELECT MIN(PK_Key2)
FROM Dim_Geo dg1
WHERE UPPER(dg1.Geo) = (SELECT UPPER(dg2.Geo)
FROM Dim_Geo dg2
WHERE dg2.PK_Key2 = f1.FK_KEY2)
);
Step 2 delete duplicated
This will delete all duplicated and keep the one with smaller id
DELETE FROM Dim_Ctry dc1
WHERE EXISTS (SELECT PK_Key1
FROM Dim_Ctry dc2
WHERE dc1.PK_Key1 > dc2.PK_Key1
and UPPER(dc1.Country) = UPPER(dc2.Country)
Step 3 update the text
You should update to lower or upper to standard format.
UPDATE Dim_Ctry
SET Country = UPPER(Country)
debug query
SELECT f1.PK_Key15, f1.FK_KEY1, f1.FK_KEY2,
(SELECT UPPER(dc2.Country)
FROM Dim_Ctry dc2
WHERE dc2.PK_Key1 = f1.FK_KEY1
) as CurrentName,
(SELECT MIN(PK_Key1)
FROM Dim_Ctry dc1
WHERE UPPER(dc1.Country) = (SELECT UPPER(dc2.Country) FROM Dim_Ctry dc2 WHERE dc2.PK_Key1 = f1.FK_KEY1) ) as minKey
FROM Fact1 f1

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
;