Update query for two tables in oracle based on multiple conditions - sql

Consider i have two table train_reserve and reserve:
train_reserve:
ChangeId
C_Id
Process
Download
trainId
Status
SDate
EDate
Book_date
L_date
BookId
1
1001
1
A
1995
B
05-APR-22
06-APR-22
10-MAR-22
11-MAR-22
111
2
1001
2
B
1995
M
05-APR-22
08-APR-22
10-MAR-22
11-MAR-22
111
3
1002
1
B
1995
B
12-APR-22
14-APR-22
10-MAR-22
11-MAR-22
222
4
1002
2
C
1995
M
12-APR-22
13-APR-22
10-MAR-22
11-MAR-22
222
5
1003
1
A
1995
B
25-MAY-22
25-MAY-22
10-MAR-22
11-MAR-22
333
6
1004
1
A
1995
B
19-MAR-22
20-MAR-22
10-MAR-22
11-MAR-22
444
7
1004
1
B
1995
B
19-MAR-22
20-MAR-22
10-MAR-22
11-MAR-22
555
reserve:
C_Id
trainId
SDate
EDate
L_date
BookId
1001
1995
05-APR-22
08-APR-22
11-MAR-22
111
1002
1995
12-APR-22
13-APR-22
11-MAR-22
222
1003
1995
25-MAY-22
25-MAY-22
11-MAR-22
333
1004
1995
19-MAR-22
20-MAR-22
11-MAR-22
444
1005
1995
19-MAR-22
20-MAR-22
11-MAR-22
555
Below is the input from user:
C_id=1, Process=(1,2), Download=(A,B,C), trainId=1995, Status=(B),Sdate=null,Edate=null,Book_date>='10-MAR-22',L_date=null.
User want to update BookId=null in both tables when C_id>=1001 and Status is B only . i.e I want below output:
train_reserve:
ChangeId
C_Id
Process
Download
trainId
Status
SDate
EDate
Book_date
L_date
BookId
1
1001
1
A
1995
B
05-APR-22
06-APR-22
10-MAR-22
11-MAR-22
111
2
1001
2
B
1995
M
05-APR-22
08-APR-22
10-MAR-22
11-MAR-22
111
3
1002
1
B
1995
B
12-APR-22
14-APR-22
10-MAR-22
11-MAR-22
222
4
1002
2
C
1995
M
12-APR-22
13-APR-22
10-MAR-22
11-MAR-22
222
5
1003
1
A
1995
B
25-MAY-22
25-MAY-22
10-MAR-22
11-MAR-22
null
6
1004
1
A
1995
B
19-MAR-22
20-MAR-22
10-MAR-22
11-MAR-22
null
7
1004
1
B
1995
B
19-MAR-22
20-MAR-22
10-MAR-22
11-MAR-22
null
reserve:
C_Id
trainId
SDate
EDate
L_date
BookId
1001
1995
05-APR-22
08-APR-22
11-MAR-22
111
1002
1995
12-APR-22
13-APR-22
11-MAR-22
222
1003
1995
25-MAY-22
25-MAY-22
11-MAR-22
null
1004
1995
19-MAR-22
20-MAR-22
11-MAR-22
null
1005
1995
19-MAR-22
20-MAR-22
11-MAR-22
null
I am currently using two update statements as below
update train_reserve a
set a.BookId=null
where a.C_Id>=1001
and a.trainId=1995
and a.Process in (1,2)
and a.Download in ('A','B','C')
and a.Status='B'
and a.Book_date>='10-MAR-22'
and not exists (select 1
from train_reserve b
where a.C_Id = b.C_Id
and b.Status='M');
update reserve
set BookId = null
where a.C_Id in (select a.C_Id
from train_reserve a
where a.C_Id >= 1001
and a.trainId=1995
and a.Process in (1,2)
and a.Download in ('A','B','C')
and a.Status='B'
and a.Book_date>='10-MAR-22'
and not exists (select 1
from train_reserve b
where a.C_Id = b.C_Id
and b.Status='M'));
But second query above takes long time to update since i am fetching data from 1st table then updating reserve table.
Is there optimized way to achieve above result?

Related

Get Data in a row with specific values

I Have a series of data like example below:
Customer
Date
Value
a
2022-01-02
100
a
2022-01-03
100
a
2022-01-04
100
a
2022-01-05
100
a
2022-01-06
100
b
2022-01-02
100
b
2022-01-03
100
b
2022-01-04
100
b
2022-01-05
100
b
2022-01-06
090
b
2022-01-07
100
c
2022-02-03
100
c
2022-02-04
100
c
2022-02-05
100
c
2022-02-06
100
c
2022-02-07
100
d
2022-04-10
100
d
2022-04-11
100
d
2022-04-12
100
d
2022-04-13
100
d
2022-04-14
100
d
2022-04-15
090
e
2022-04-10
100
e
2022-04-11
100
e
2022-04-12
080
e
2022-04-13
070
e
2022-04-14
100
e
2022-04-15
100
The result I want are customer A,C and D only. Because A, C and D have value 100 for 5 days in a row.
The start date of each customer is different.
What is the query in BigQuery I need to write for that case above?
Thank you so much
Would you consider below query ?
SELECT DISTINCT Customer
FROM sample_table
QUALIFY 5 = COUNTIF(Value = 100) OVER (
PARTITION BY Customer ORDER BY UNIX_DATE(Date) RANGE BETWEEN 4 PRECEDING AND CURRENT ROW
);
+-----+----------+
| Row | Customer |
+-----+----------+
| 1 | a |
| 2 | c |
| 3 | d |
+-----+----------+
Note that it assumes Date column has DATE type.

Join on same column multiple times

how do I join on the same column multiple times, one of the tables is a configuration table with values and other is the data table.
T1:
ID Seq Code1 Code2 Code3
1 001 101 203 305
1 002 107
2 001 103
3 005 213
4 009 320
5 001 101 314
T2 (Config table):
Value Description
101 Strawberry
103 Raspberry
107 Blueberry
111 Banana
203 Cashews
213 Almonds
305 Bellpepper
320 Tomatoes
314 Potatoes
I need to display the code and its relevant description for each ID.
Expected Output:
ID Code1 Description Code2 Description Code3 Description
1 101 Strawberry 203 Cashews 305 Bellpepper
1 107 Blueberry
2 103 Raspberry
3 213 Almonds
4 320 Tomatoes
5 101 Strawberry 314 Potatoes
This is what I have tried so far, however, it is not giving me the desired output:
select distinct ID,code1, T2.description,
code2, T2.description, code3, T2.description
from T1,T2
where (T1.Code1=T2.Value OR T1.Code2=T2.Value or T1.Code3=T2.Value)
How can I achieve this? Sorry if my question is confusing, I can provide more details if needed.
That's multiple outer join with the t2 table:
select a.id, a.seq,
a.code1, d1.description,
a.code2, d2.description,
a.code3, d3.description
from t1 a left join t2 d1 on a.code1 = d1.value
left join t2 d2 on a.code2 = d2.value
left join t2 d3 on a.code3 = d3.value
order by a.id, a.seq;
ID SEQ CODE1 DESCRIPTIO CODE2 DESCRIPTIO CODE3 DESCRIPTIO
----- --- ---------- ---------- ---------- ---------- ---------- ----------
1 001 101 Strawberry 203 Cashews 305 Bellpepper
1 002 107 Blueberry
2 001 103 Raspberry
3 005 213 Almonds
4 009 320 Tomatoes
5 001 101 Strawberry 314 Potatoes

count of nulls over a window

I need to get the count of nulls group by ID but excluding the month and sales in group by
sample data
id custname reportdate sales
1 xx 31-JAN-17 1256
1 xx 31-MAR-17 <null>
1 xx 30-JUN-17 5678
1 xx 31-DEC-17 <null>
1 xx 31-JAN-18 1222
1 xx 31-MAR-18 <null>
1 xx 30-JUN-18 5667
1 xx 31-DEC-18 7890
2 yy 31-JAN-17 1223
2 yy 31-APR-17 3435
2 yy 30-JUN-17 <null>
2 yy 31-DEC-17 4567
2 yy 31-JAN-18 5678
2 yy 31-APR-18 <null>
2 yy 30-JUN-18 <null>
2 yy 31-DEC-18 2345
what i need as a output
id custname reportdate sales count(Sales nulls)
1 xx 31-JAN-17 1256 2
1 xx 31-MAR-17 <null> 2
1 xx 30-JUN-17 5678 2
1 xx 31-DEC-17 <null> 2
1 xx 31-JAN-18 1222 1
1 xx 31-MAR-18 <null> 1
1 xx 30-JUN-18 5667 1
1 xx 31-DEC-18 7890 1
2 yy 31-JAN-17 1223 1
2 yy 31-APR-17 3435 1
2 yy 30-JUN-17 <null> 1
2 yy 31-DEC-17 9643 1
2 yy 31-JAN-18 5678 2
2 yy 31-APR-18 <null> 2
2 yy 30-JUN-18 <null> 2
2 yy 31-DEC-18 2345 2
As you can see i have multiple years and i need the partition on id and year NOT MONTH
Using a case expression in count window function.
select t.*,count(case when sales is null then 1 end) over(partition by id) as null_cnt_per_id
from tbl t

How to eliminate duplicates in a SQL table with the following values?

S_No. Name HRA
1 SS 123
2 SS 123
3 SS 123
4 SS 124
5 SA 222
6 SA 222
7 SA 221
8 SE 222
9 SE 123
10 SE 123
Desired Result
S_No. Name HRA
1 SS 123
4 SS 124
5 SA 222
7 SA 221
8 SE 222
9 SE 123
select min(s_no), name, hra
from table_name
group by name, hra

Python Pandas Combining 2 df by keys

I'm trying to combine these two dataframes:
df1 =
ID1 ID2
111 1001
112 1002
113 1003
114 1004
115 1005
df2 =
ID1 Name Age
111 ABC 20
111 ABC 21
1001 ABC 22
1002 QAZ 18
1002 QAZ 19
1002 QAZ 20
113 XYZ 25
113 XYZ 25
to get an output like this:
ID Name Age ID1 ID2
111 ABC 20 111 1001
111 ABC 21 111 1001
1001 ABC 22 111 1001
1002 QAZ 18 112 1002
1002 QAZ 19 112 1002
1002 QAZ 20 112 1002
113 XYZ 25 113 1003
113 XYZ 25 113 1003
Is this possible?
Thanks in advance!
merge + combine_first PS: I think the ID1 in df2 should be ID
df2.merge(df1,left_on='ID',right_on='ID1',how='left').\
combine_first(df2.merge(df1,left_on='ID',right_on='ID2',how='left'))
Out[912]:
ID Name Age ID1 ID2
0 111 ABC 20 111.0 1001.0
1 111 ABC 21 111.0 1001.0
2 1001 ABC 22 111.0 1001.0
3 1002 QAZ 18 112.0 1002.0
4 1002 QAZ 19 112.0 1002.0
5 1002 QAZ 20 112.0 1002.0
6 113 XYZ 25 113.0 1003.0
7 113 XYZ 25 113.0 1003.0