I want last column 'Output' as stated in table. here the logic is :
for row 1 : sum of LBKUM & weekly_qty
for row 2 : sum of output of row 1 & weekly_qty of row 2
for row 3 : sum of output of row 2 & weekly_qty of row 3
for row 4 : sum of output of row 3 & weekly_qty of row 4
and so on.
Unlike other running total, I want LBKUM only once (in first row calculation) and in the next steps, output of previous row should be considered as shown in the description.
I hope this much would be sufficient.
Thanks in advance.
LOGSYS
MATNR
PLANT
LBKUM
QTY_WITHDRAWL
PLUS_QTY
WEEK
WEEKLY_QTY
Output
SAP
123456789
1234
1408
387
484
06
97
1505
SAP
123456789
1234
1408
1238
2080
07
842
2347
SAP
123456789
1234
1408
1826
1600
08
-226
2121
SAP
123456789
1234
1408
1786
1920
09
134
2255
SAP
123456789
1234
1408
1445
1120
10
-325
1930
SAP
123456789
1234
1408
1224
800
11
-424
1506
SAP
123456789
1234
1408
1299
1280
12
-19
1487
You want something like:
SELECT week,
FIRST_VALUE(lbkum) OVER (ORDER BY week)
+ SUM(weekly_qty) OVER (ORDER BY week) AS running_total
FROM table_name
Which, for the sample data:
CREATE TABLE table_name (LOGSYS, MATNR, PLANT, LBKUM, QTY_WITHDRAWL, PLUS_QTY, WEEK, WEEKLY_QTY, Output) AS
SELECT 'SAP', 123456789, 1234, 1408, 387, 484, 06, 97, 1505 FROM DUAL UNION ALL
SELECT 'SAP', 123456789, 1234, 1408, 1238, 2080, 07, 842, 2347 FROM DUAL UNION ALL
SELECT 'SAP', 123456789, 1234, 1408, 1826, 1600, 08, -226, 2121 FROM DUAL UNION ALL
SELECT 'SAP', 123456789, 1234, 1408, 1786, 1920, 09, 134, 2255 FROM DUAL UNION ALL
SELECT 'SAP', 123456789, 1234, 1408, 1445, 1120, 10, -325, 1930 FROM DUAL UNION ALL
SELECT 'SAP', 123456789, 1234, 1408, 1224, 800, 11, -424, 1506 FROM DUAL UNION ALL
SELECT 'SAP', 123456789, 1234, 1408, 1299, 1280, 12, -19, 1487 FROM DUAL;
Outputs:
WEEK
RUNNING_TOTAL
6
1505
7
2347
8
2121
9
2255
10
1930
11
1506
12
1487
fiddle
Related
This is what my table looks like:
RefNum
Year
CorrespVNum
Proceeds
BaseCost
12345
2019
54321
12345.69
10000.00
12345
2019
54321
500.69
6000.00
12345
2019
65432
12345.69
10000.00
12345
2019
65432
500.69
6000.00
23456
2020
33344
50000.00
15000.00
34567
2021
11155
521.00
1000.00
34567
2021
11155
17.00
800.00
34567
2021
11155
85.00
100.00
I want the result to look like this:
RefNum
Year
CorrespVNum
TotalProceeds
TotalBaseCost
12345
2019
54321
12846.38
16000.00
12345
2019
65432
12846.38
16000.00
23456
2020
33344
50000.00
15000.00
34567
2021
11155
623.00
1900.00
So the matching criteria are the Refnum, Year and CorrespVnum. I have been messing around with a CTE query and I can't seem to get it to work. It works if I only have 2 matching rows but if there are more than 2 then it doesn't work.
Does anyone have any idea how to do this?
select RefNum
,Year
,CorrespVNum
,sum(Proceeds) as TotalProceeds
,sum(BaseCost) as TotalBaseCost
from t
group by RefNum, Year, CorrespVNum
RefNum
Year
CorrespVNum
TotalProceeds
TotalBaseCost
12345
2019
54321
12845
16000
12345
2019
65432
12845
16000
23456
2020
33344
50000
15000
34567
2021
11155
623
1900
Fiddle
you can try this, keep it simple:
with table_1 (Refnum,Year,CorrespVNum,Proceeds,BaseCost)
as
(
Select '12345', '2019', '54321',12345.69,10000
Union all Select '12345', '2019', '54321',500.69,6000
Union all Select '12345', '2019', '65432',12345.69,10000
Union all Select '12345', '2019', '65432',500.69,6000
Union all Select '34567', '2021', '33344',500000,15000
Union all Select '34567', '2021', '11155',521,1000
Union all Select '34567', '2021', '11155',17,800
Union all Select '34567', '2021', '11155',85,100
)
Select
RefNum,
Year,
CorrespVNum,
Sum(BaseCost) as TotalCaseCost
from
table_1
group by
RefNum,
Year,
CorrespVNum
It's me again - I have a new homework and I don't get any further.
The task is:
Find out the date of flight(DATE_FLY), flight number(FLY_NR), manufacturer(MANUF), type (TYP) and serial number (SER_NR) of all flights that fly from Frankfurt to Dallas between 10.11.2013 and 20.11.2013.
This is the departure_table:
DATE_FLY
FLY_NR
MANUF
TYP
PER_NR
SER_NR
TIME_START
06.07.13
LH-888
Boeing
B747
9fg-he-ztu8
10010071
11.23
08.10.13
LH-238
Airbus
A320
z3et-bwe7
10010072
22.06
13.11.13
LH-341
Boeing
B737
ba23-0012
10010001
10.23
14.11.13
LH-358
Boeing
B737
ba23-0012
10010001
8.17
13.11.13
LH-553
Boeing
B777
xv23-0889
10010002
16.53
15.11.13
LH-421
Boeing
B777
xv56-3142
10010002
14.45
17.11.13
LH-789
Airbus
A330
45-6789
10010003
8.11
14.11.13
LH-112
Boeing
B737
ba23-0034
10010001
8.14
17.11.13
LH-421
Boeing
B777
xv23-0889
10010002
16.26
18.11.13
LH-223
Airbus
A380
ab-45-6xf
10010004
9.45
19.11.13
LH-634
Airbus
A350
5478-awe3
10010005
20.25
18.02.14
LH-238
Airbus
A320
z3et-bwe7
10010072
23.06
And this is the fly_table that I need to join:
FLY_NR
START_FLY
DEST_FLY
TIME_FLY
KM
LH-341
Saarbruecken
Hamburg
1.2
490
LH-358
Saarbruecken
Leipzig
1.1
430
LH-553
Leipzig
Hamburg
.5
290
LH-112
Luxemburg
London
1.1
480
LH-421
Luxemburg
Ankara
2.5
2300
LH-789
Luxemburg
New-York
3.5
8300
LH-223
Frankfurt
Dallas
3.9
8600
LH-634
Frankfurt
Moskau
2.3
2020
LH-888
Frankfurt
Peking
9.5
7780
LH-238
Muenchen
Berlin
1.1
479
I wrote the following query but it showed me "no data found":
select
dp.date_fly, dp.fly_nr, dp.manuf, dp.typ, dp.ser_nr
from
departure_table dp, fly_table fl
where
dp.fly_nr = fl.fly_nr
and start_fly = 'Frankfurt'
and dest_fly = 'Dallas'
and dp.date_fly between 10.11.2013 and 20.11.2013;
I've tried a simple join but I still only got the message "no data found":
select
dp.date_fly, dp.fly_nr, dp.manuf, dp.typ, dp.ser_nr
from
departure_table dp, fly_table fl
where
dp.fly_nr = fl.fly_nr;
I don't know what am I doing wrong... I would be very thankful if somebody could help to solve this problem with the join function.
I need to get this result:
DATE_FLY
FLY_NR
MANUF
TYP
SER_NR
18-NOV-13
LH-223
Airbus
A380
10010004
Thank you!
The column FLY_DATE has a VARCHAR2 format
This is bad practice. If you have a date then store it as a date. If you have to store it as a string (really, don't do that) then store it using ISO8601 formatting YYYY-MM-DD which can be sorted alphabetically into date-order (and not DD-MM-YYYY which cannot be easily sorted).
Since you have it in a (mostly unusable) string format, you need to convert it to a DATE using the TO_DATE function and compare it to DATE literals:
select dp.date_fly,
dp.fly_nr,
dp.manuf,
dp.typ,
dp.ser_nr
from departure_table dp
INNER JOIN fly_table fl
ON dp.fly_nr = fl.fly_nr
where start_fly = 'Frankfurt'
and dest_fly = 'Dallas'
and TO_DATE(dp.date_fly, 'DD.MM.YYYY') between DATE '2013-11-10' and DATE '2013-11-20';
Which, for the sample data:
CREATE TABLE departure_table (DATE_FLY, FLY_NR, MANUF, TYP, PER_NR, SER_NR, TIME_START) AS
SELECT '06.07.2013', 'LH-888', 'Boeing', 'B747', '9fg-he-ztu8', 10010071, 11.23 FROM DUAL UNION ALL
SELECT '08.10.2013', 'LH-238', 'Airbus', 'A320', 'z3et-bwe7', 10010072, 22.06 FROM DUAL UNION ALL
SELECT '13.11.2013', 'LH-341', 'Boeing', 'B737', 'ba23-0012', 10010001, 10.23 FROM DUAL UNION ALL
SELECT '14.11.2013', 'LH-358', 'Boeing', 'B737', 'ba23-0012', 10010001, 8.17 FROM DUAL UNION ALL
SELECT '13.11.2013', 'LH-553', 'Boeing', 'B777', 'xv23-0889', 10010002, 16.53 FROM DUAL UNION ALL
SELECT '15.11.2013', 'LH-421', 'Boeing', 'B777', 'xv56-3142', 10010002, 14.45 FROM DUAL UNION ALL
SELECT '17.11.2013', 'LH-789', 'Airbus', 'A330', '45-6789', 10010003, 8.11 FROM DUAL UNION ALL
SELECT '14.11.2013', 'LH-112', 'Boeing', 'B737', 'ba23-0034', 10010001, 8.14 FROM DUAL UNION ALL
SELECT '17.11.2013', 'LH-421', 'Boeing', 'B777', 'xv23-0889', 10010002, 16.26 FROM DUAL UNION ALL
SELECT '18.11.2013', 'LH-223', 'Airbus', 'A380', 'ab-45-6xf', 10010004, 9.45 FROM DUAL UNION ALL
SELECT '19.11.2013', 'LH-634', 'Airbus', 'A350', '5478-awe3', 10010005, 20.25 FROM DUAL UNION ALL
SELECT '18.02.2014', 'LH-238', 'Airbus', 'A320', 'z3et-bwe7', 10010072, 23.06 FROM DUAL;
CREATE TABLE fly_table (FLY_NR, START_FLY, DEST_FLY, TIME_FLY, KM) AS
SELECT 'LH-341', 'Saarbruecken', 'Hamburg', 1.2, 490 FROM DUAL UNION ALL
SELECT 'LH-358', 'Saarbruecken', 'Leipzig', 1.1, 430 FROM DUAL UNION ALL
SELECT 'LH-553', 'Leipzig', 'Hamburg', .5, 290 FROM DUAL UNION ALL
SELECT 'LH-112', 'Luxemburg', 'London', 1.1, 480 FROM DUAL UNION ALL
SELECT 'LH-421', 'Luxemburg', 'Ankara', 2.5, 2300 FROM DUAL UNION ALL
SELECT 'LH-789', 'Luxemburg', 'New-York', 3.5, 8300 FROM DUAL UNION ALL
SELECT 'LH-223', 'Frankfurt', 'Dallas', 3.9, 8600 FROM DUAL UNION ALL
SELECT 'LH-634', 'Frankfurt', 'Moskau', 2.3, 2020 FROM DUAL UNION ALL
SELECT 'LH-888', 'Frankfurt', 'Peking', 9.5, 7780 FROM DUAL UNION ALL
SELECT 'LH-238', 'Muenchen', 'Berlin', 1.1, 479 FROM DUAL;
Outputs:
DATE_FLY
FLY_NR
MANUF
TYP
SER_NR
18.11.2013
LH-223
Airbus
A380
10010004
fiddle
key1
key2
val
23
215
4489
23
216
4489
86
326
5245
86
325
4489
86
323
4489
04
369
1200
04
370
1673
04
368
4489
10
402
1673
10
400
5971
10
404
1200
10
401
9189
Output should be like this
key1
key2
val
86
326
5245
04
369
1200
04
370
1673
04
368
4489
10
402
1673
10
400
5971
10
404
1200
10
401
9189
How to compare two rows having same key1 but different key2 where val is same for key2's.
I tried having and group by query but as this outcome render from views and 3 different tables, which is hard to understand for me.
Any help will be appreciated
Added :
where key1 is same for key2 having same val need to exclude
but when
key1 is same for key2 having different val need to show as outcome
To me, it looks like
SQL> WITH
2 test (key1, key2, val)
3 AS
4 -- sample data
5 (SELECT '23', 215, 4489 FROM DUAL
6 UNION ALL
7 SELECT '23', 216, 4489 FROM DUAL
8 UNION ALL
9 SELECT '86', 326, 5245 FROM DUAL
10 UNION ALL
11 SELECT '86', 325, 4489 FROM DUAL
12 UNION ALL
13 SELECT '86', 323, 4489 FROM DUAL
14 UNION ALL
15 SELECT '04', 369, 1200 FROM DUAL
16 UNION ALL
17 SELECT '04', 370, 1673 FROM DUAL
18 UNION ALL
19 SELECT '04', 368, 4489 FROM DUAL
20 UNION ALL
21 SELECT '10', 402, 1673 FROM DUAL
22 UNION ALL
23 SELECT '10', 400, 5971 FROM DUAL
24 UNION ALL
25 SELECT '10', 404, 1200 FROM DUAL
26 UNION ALL
27 SELECT '10', 401, 9189 FROM DUAL),
28 temp
29 AS
30 -- count > 1 means that there are values that match
31 ( SELECT key1, val, COUNT (*) cnt
32 FROM test
33 GROUP BY key1, val)
34 SELECT a.key1, a.key2, a.val
35 FROM test a
36 WHERE (a.key1, a.val) IN (SELECT b.key1, b.val
37 FROM temp b
38 WHERE b.cnt = 1) --> no match
39 ORDER BY a.key1, a.key2;
KEY1 KEY2 VAL
-------- ---------- ----------
04 368 4489
04 369 1200
04 370 1673
10 400 5971
10 401 9189
10 402 1673
10 404 1200
86 326 5245
8 rows selected.
SQL>
If sample data come from a query you already wrote, then you'd use it as a CTE:
with your_query as
(select ... --> put your query in here
from ...
where ...
),
-- code I wrote goes here, starting from line #28
temp as
...
After you posted your query, it would be something like this; note that I don't know which columns you want to compare because there are no longer KEY1, KEY2 and VAL columns; you'll have to fix it yourself.
WITH
your_query
AS
( SELECT COUNT (*) cnt,
t2.ORIGINATOR_ID,
t3.name,
t4.MULTI_TRANCHE_FLAG,
v1.SOURCE_OF_DEAL,
ta1.PRICING_DATE
FROM vw_origination_deal_advice ta1
LEFT JOIN vw_orig_deal_advice_summary v1
ON v1.deal_id = ta1.orig_deal_advice_id
LEFT JOIN tbl_issue_tranche t4 ON t4.id = ta1.ISSUE_TRANCHE_ID
LEFT JOIN tbl_issue_originator t2
ON ta1.issue_tranche_id = t2.ISSUE_TRANCHE_ID
LEFT JOIN tbl_staff t3 ON t2.originator_id = t3.staff_id
WHERE ta1.ISSUE_TRANCHE_ID IN
( SELECT ta2.ISSUE_TRANCHE_ID
FROM vw_origination_deal_advice ta2
GROUP BY ta2.ISSUE_TRANCHE_ID)
AND ta1.PRICING_DATE LIKE '%-21%'
AND t4.MULTI_TRANCHE_FLAG = 1
GROUP BY ta1.orig_deal_advice_id,
ta1.ISSUE_TRANCHE_ID,
t4.ACTIVE,
t2.ORIGINATOR_ID,
t3.name,
t4.MULTI_TRANCHE_FLAG,
v1.SOURCE_OF_DEAL,
ta1.PRICING_DATE),
temp
AS
-- count > 1 means that there are values that match.
-- As KEY1, KEY2, VAL don't exist in your query, you'll have to use appropriate
-- names from in the rest of the query
( SELECT key1, val, COUNT (*) cnt
FROM test
GROUP BY key1, val)
SELECT a.key1, a.key2, a.val
FROM test a
WHERE (a.key1, a.val) IN (SELECT b.key1, b.val
FROM temp b
WHERE b.cnt = 1) --> no match
ORDER BY a.key1, a.key2;
I'd like to create a new column by dividing current year by its latest year in Col_1 and Col_2 respectively for each group. Then, divide the two divisions.
Methodology: Calculate (EachYrCol_1/Yr2000Col_1)/(EachYrCol_2/Yr2000Col_2) for each group
See example below:
Year
Group
Col_1
Col_2
New Column
1995
A
100
11
(100/600)/(11/66)
1996
A
200
22
(200/600)/(22/66)
1997
A
300
33
(300/600)/(33/66)
1998
A
400
44
.............
1999
A
500
55
.............
2000
A
600
66
.............
1995
B
700
77
(700/1200)/(77/399)
1996
B
800
88
(800/1200)/(88/399)
1997
B
900
99
(900/1200)/(99/399)
1998
B
1000
199
.............
1999
B
1100
299
.............
2000
B
1200
399
.............
Sample dataset:
import pandas as pd
df = pd.DataFrame({'Year':[1995, 1996, 1997, 1998, 1999, 2000,1995, 1996, 1997, 1998, 1999, 2000],
'Group':['A', 'A', 'A','A', 'A', 'A', 'B', 'B', 'B', 'B', 'B', 'B'],
'Col_1':[100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200],
'Col_2':[11, 22, 33, 44, 55, 66, 77, 88, 99, 199, 299, 399]})
Use GroupBy.transform with GroupBy.last for helper DataFrame, so possible divide each column:
df1 = df.groupby('Group').transform('last')
df['New'] = df['Col_1'].div(df1['Col_1']).div(df['Col_2'].div(df1['Col_2']))
print (df)
Year Group Col_1 Col_2 New
0 1995 A 100 11 1.000000
1 1996 A 200 22 1.000000
2 1997 A 300 33 1.000000
3 1998 A 400 44 1.000000
4 1999 A 500 55 1.000000
5 2000 A 600 66 1.000000
6 1995 B 700 77 3.022727
7 1996 B 800 88 3.022727
8 1997 B 900 99 3.022727
9 1998 B 1000 199 1.670854
10 1999 B 1100 299 1.223244
11 2000 B 1200 399 1.000000
In order to verify if Deliveries are done on time, I need to match delivery Documents to PO schedule lines (SchLin) based on the comparison between Required Quantity (ReqQty) and Delivered Quantity (DlvQty).
The Delivery Docs have a reference to the PO and POItm but not to the SchLin.
Once a Delivery Doc is assigned to a Schedule Line I can calculate the Delivery Delta (DlvDelta) as the number of days it was delivered early or late compared to the requirement (ReqDate).
Examples of the two base tables are as follows:
Schedule lines
PO POItm SchLin ReqDate ReqQty
123 1 1 10/11 20
123 1 2 30/11 30
124 2 1 15/12 10
124 2 2 24/12 15
Delivery Docs
Doc Item PO POItm DlvDate DlvQty
810 1 123 1 29/10 12
816 1 123 1 02/11 07
823 1 123 1 04/11 13
828 1 123 1 06/11 08
856 1 123 1 10/11 05
873 1 123 1 14/11 09
902 1 124 2 27/11 05
908 1 124 2 30/11 07
911 1 124 2 08/12 08
923 1 124 2 27/12 09
Important: Schedule Lines and Deliveries should have the same PO and POItm.
The other logic to link is to sum the DlvQty until we reach (or exceed) ReqQty.
Those deliveries are then linked to the schedule line. Subsequent deliveries are used for the following schedule line(s). A delivery schould be matched to only one schedule line.
After comparing the ReqQty and DlvQty the assignments should result in following:
Result
Doc Item PO POItm Schlin ReqDate DlvDate DlvDelta
810 1 123 1 1 10/11 29/10 -11
816 1 123 1 1 10/11 02/11 -08
823 1 123 1 1 10/11 04/11 -06
828 1 123 1 2 30/11 06/11 -24
856 1 123 1 2 30/11 10/11 -20
873 1 123 1 2 30/11 14/11 -16
902 1 124 2 1 15/12 27/11 -18
908 1 124 2 1 15/12 30/11 -15
911 1 124 2 2 24/12 08/12 -16
923 1 124 2 2 24/12 27/12 +03
Up till now, I have done this with loops using cursors but performance is rather sluggish.
Is there another way in SQL (script) using e.g. joins by comparing measures to achieve the same result?
Regards,
Eric
If you can express the rule for matching a delivery with a schedule line, you can produce the results you want in a single query. And, yes, I promise it will be faster (and simpler) than executing the same logic in loops on cursors.
I can't reproduce your exact results because I don't quite understand how the two tables relate. Hopefully from the code below you'll be able to figure it out by adjusting the join criteria.
I don't have your DBMS. My code uses SQLite, which has its own peculiar date functions. You'll have to substitute the ones your system provides. In any event, I can't recommend 5-character strings for dates. Use a datetime type if you have one, and include 4-digit years regardless. Else how many days are there between Christmas and New Years Day?
create table S (
PO int not NULL,
POItm int not NULL,
SchLin int not NULL,
ReqDate char not NULL,
ReqQty int not NULL,
primary key (PO, POItm, SchLin)
);
insert into S values
(123, 1, 1, '10/11', 20 ),
(123, 1, 2, '30/11', 30 ),
(124, 2, 1, '15/12', 10 ),
(124, 2, 2, '24/12', 15 );
create table D (
Doc int not NULL,
Item int not NULL,
PO int not NULL,
POItm int not NULL,
DlvDate char not NULL,
DlvQty int not NULL,
primary key (Doc, Item)
);
insert into D values
(810, 1, 123, 1, '29/10', 12 ),
(816, 1, 123, 1, '02/11', 07 ),
(823, 1, 123, 1, '04/11', 13 ),
(828, 1, 123, 1, '06/11', 08 ),
(856, 1, 123, 1, '10/11', 05 ),
(873, 1, 123, 1, '14/11', 09 ),
(902, 1, 124, 2, '27/11', 05 ),
(908, 1, 124, 2, '30/11', 07 ),
(911, 1, 124, 2, '08/12', 08 ),
(923, 1, 124, 2, '27/12', 09 );
select D.Doc, D.Item, D.PO, S.SchLin, S.ReqDate, D.DlvDate
, cast(
julianday('2018-' || substr(DlvDate, 4,2) || '-' || substr(DlvDate, 1,2))
- julianday('2018-' || substr(ReqDate, 4,2) || '-' || substr(ReqDate, 1,2))
as int) as DlvDelta
from S join D on S.PO = D.PO and S.POItm = D.POItm
;
Result:
Doc Item PO SchLin ReqDate DlvDate DlvDelta
---------- ---------- ---------- ---------- ---------- ---------- ----------
810 1 123 1 10/11 29/10 -12
810 1 123 2 30/11 29/10 -32
816 1 123 1 10/11 02/11 -8
816 1 123 2 30/11 02/11 -28
823 1 123 1 10/11 04/11 -6
823 1 123 2 30/11 04/11 -26
828 1 123 1 10/11 06/11 -4
828 1 123 2 30/11 06/11 -24
856 1 123 1 10/11 10/11 0
856 1 123 2 30/11 10/11 -20
873 1 123 1 10/11 14/11 4
873 1 123 2 30/11 14/11 -16
902 1 124 1 15/12 27/11 -18
902 1 124 2 24/12 27/11 -27
908 1 124 1 15/12 30/11 -15
908 1 124 2 24/12 30/11 -24
911 1 124 1 15/12 08/12 -7
911 1 124 2 24/12 08/12 -16
923 1 124 1 15/12 27/12 12
923 1 124 2 24/12 27/12 3