Full Date Range - oracle

1st time posting here, so sorry if I messed something up.
I'm trying to figure out how many units pre day are being used across multiple products given a date range.
So if I had a table like this:
Product_id
Start_date
End_date
Units
1
07/07/2021
07/09/2021
2
2
07/08/2021
07/10/2021
4
3
07/12/2021
07/12/2021
7
The output should be something like:
Date
Units
07/07/2021
2
07/08/2021
6
07/09/2021
6
07/10/2021
4
07/11/2021
0
07/12/2021
7

Here's one option; read comments within code.
SQL> with
2 calendar as
3 -- all dates between the first START_DATE and the last END_DATE.
4 -- You need it for outer join with data you have.
5 (select mindat + level - 1 as datum
6 from (select min(start_date) mindat,
7 max(end_date) maxdat
8 from test
9 )
10 connect by level <= maxdat - mindat + 1
11 )
12 -- final query
13 select c.datum,
14 nvl(sum(t.units), 0) units
15 from calendar c left join test t on c.datum between t.start_date and t.end_date
16 group by c.datum
17 order by c.datum;
DATUM UNITS
---------- ----------
07/07/2021 2
07/08/2021 6
07/09/2021 6
07/10/2021 4
07/11/2021 0
07/12/2021 7
6 rows selected.
SQL>

Related

search in text using subtext in Oracle PLSQL

I have this query in master_t table that hold ration_category column and many number of sectors in sectors column like this 'BN:INS' or 'BN' or 'BN:IM:INS' etc..
select distinct ratio_category d from master_t
where status = 'Y' and (SECTORS = :P23_SECTORS or
(INSTR(':'||:SECTORS ||':',:P23_SECTORS)>0 OR UPPER(:P23_SECTORS) = 'ALL')) order by ratio_category
P23_SECTORS= 'BN:INS'
SECTORS='INS:MFI:SB:BN'
: is a separator of multi data
I need to check if data inside P23_sectors are exists in SECTORS variable ,
but this query doesn't get data because the multi data separator
Is there anyway to adjust the query so I could compare subtext with full text
note : the order is different.
Expected output :
LL
PP
CC
Thanks
Here's one option (read comments within code):
SQL> with master_t (ratio_category, sectors) as
2 -- sample data
3 (select 1, 'INS:MFI:SB:BN' from dual union all
4 select 2, 'BN:LF' from dual
5 ),
6 split_t as
7 -- split SECTORS into rows
8 (select ratio_category,
9 sectors,
10 regexp_substr(sectors, '[^:]+', 1, column_value) sec
11 from master_t cross join
12 table(cast(multiset(select level from dual
13 connect by level <= regexp_count(sectors, ':') + 1
14 ) as sys.odcinumberlist))
15 ),
16 split_23 as
17 -- split P23_SECTORS into rows
18 (select regexp_substr('&&P23_SECTORS', '[^:]+', 1, level) sec,
19 regexp_count('&&P23_SECTORS', ':') + 1 cnt
20 from dual
21 connect by level <= regexp_count('&&P23_SECTORS', ':') + 1
22 )
23 -- return rows that contain complete P23_SECTORS value(s)
24 select t.ratio_category, t.sectors
25 from split_t t join split_23 s on s.sec = t.sec
26 group by t.ratio_category, t.sectors
27 having count(*) = max(s.cnt);
Enter value for p23_sectors: BN:INS
RATIO_CATEGORY SECTORS
-------------- -------------
1 INS:MFI:SB:BN
SQL>
Pay attention to comments people posted. They do have serious experience with programming and you'd rather listen to what they say and thank them for spending time to check your problem. Your reply to Ed is rather rude; if I were Ed, I'd make sure not to respond to any of your future questions (read: I'd let you solve your own problems).

Create a product base table by date

I want to create a query that returns number of active products by colander date. I don’t have calendar dim table in database.
Current table
Product_name|prod_id|start_date|end_date
P1|1234|02/01/2020|30/05/2020
P1|2345|02/01/2020|31/12/9999
P1|3456|03/01/2020|31/12/9999
Expected Result
Calander_date|product_name|active_base
01/01/2020|P1|0
02/01/2020|P1|2
03/01/2020|P1|3
01/06/2020|P1|2
Create your own calendar, then - either in the database, as a "real" table (row generator technique helps here), or as a CTE (as I did in the following example):
SQL> with
2 test (product_name, prod_id, start_date, end_date) as
3 -- you have that table; don't type that
4 (select 'P1', 1234, date '2020-01-02', date '2020-05-30' from dual union all
5 select 'P1', 2345, date '2020-01-02', date '9999-12-31' from dual union all
6 select 'P1', 3456, date '2020-01-03', date '9999-12-31' from dual
7 ),
8 calendar (datum) as
9 -- create your own calendar table
10 (select date '2020-01-01' + level - 1
11 from dual
12 connect by level <= 10000 --> number of days you want in calendar
13 )
14 -- final query - join!
15 select c.datum,
16 t.product_name,
17 count(*) active_base
18 from calendar c join test t on c.datum between t.start_date and t.end_date
19 group by c.datum, t.product_name
20 order by c.datum;
DATUM PR ACTIVE_BASE
---------- -- -----------
02/01/2020 P1 2
03/01/2020 P1 3
04/01/2020 P1 3
05/01/2020 P1 3
06/01/2020 P1 3
<snip>
28/05/2020 P1 3
29/05/2020 P1 3
30/05/2020 P1 3
31/05/2020 P1 2
01/06/2020 P1 2
02/06/2020 P1 2
<snip>

PL/SQL funtion with If

I have a production records system, where the user selects the date, time, area, line, shift, and model. Introduce the number of fabric pieces in one hour in the field pieces. After adding another record, the user enters again the number of pieces, but it must also appear in another field, Total pieces, the total of pieces, that is, the sum of the current one plus the previous record.
This is the table
Date-------Time---------Area-------Line----Shift-----Model----Pieces-------Total volume
8/8/20-------7--------------A-----------1---------1--------XC1--------2--------------------2
8/8/20-------8--------------A-----------1---------1--------XC1--------3--------------------5
8/8/20-------9--------------A-----------1---------1--------XC1--------2--------------------7
The function should not add anything at the beginning of the day, and the following records should be added as long as the date, line, area, shift and model are the same.
I had planned to use a PL/SQL function where if the time is 7 (the start) it show the same number that was entered in pieces, but if it is another time (8 for example), select the pieces data in the database of the record that has the same date, area, line, shift, and model but the time is the previous one (hour-1).
I don't know if this can be done, I would appreciate your help.
I wouldn't store total_volume into a table; calculate it using sum function in its analytic form. This is, after all, Oracle Apex (I presume interactive or classic report).
Here's an example (sample data from lines #1 - 14; query that actually does the job begins at line #15):
SQL> with test (datum, time, model, pieces) as -- Expected result:
2 (select date '2020-08-08', 7 , 'XC1', 2 from dual union all -- 2
3 select date '2020-08-08', 8 , 'XC1', 3 from dual union all -- 5
4 select date '2020-08-08', 9 , 'XC1', 2 from dual union all -- 7
5 --
6 select date '2020-08-09', 7 , 'XC1', 1 from dual union all -- 1
7 select date '2020-08-09', 8 , 'XC1', 3 from dual union all -- 4
8 select date '2020-08-09', 10, 'XC1', 2 from dual union all -- 6
9 select date '2020-08-09', 11, 'XC1', 1 from dual union all -- 7
10 select date '2020-08-09', 12, 'XC1', 6 from dual union all -- 13
11 --
12 select date '2020-08-09', 9 , 'XC2', 5 from dual union all -- 5
13 select date '2020-08-09', 10, 'XC2', 4 from dual -- 9
14 )
15 select datum, time, model, pieces,
16 sum(pieces) over (partition by datum, model order by time) total_volume
17 from test
18 order by datum, model, time;
DATUM TIME MOD PIECES TOTAL_VOLUME
---------- ---------- --- ---------- ------------
08/08/2020 7 XC1 2 2
08/08/2020 8 XC1 3 5
08/08/2020 9 XC1 2 7
09/08/2020 7 XC1 1 1
09/08/2020 8 XC1 3 4
09/08/2020 10 XC1 2 6
09/08/2020 11 XC1 1 7
09/08/2020 12 XC1 6 13
09/08/2020 9 XC2 5 5
09/08/2020 10 XC2 4 9
10 rows selected.
SQL>

only keep distinct rows when doing collect_set over a moving windowing function in hive

Lets say I have a hive table that has 3 rows: merchant_id, week_id, acc_id. My goal is to collect the unique customers in the previous 4 weeks for each week and I am using a moving window to do this.
My codes:
create a test table:
CREATE TABLE table_test_test (merchant_id INT, week_id INT, acc_id INT);
INSERT INTO TABLE table_test_test VALUES
(1,0,8),
(1,0,9),
(1,0,10),
(1,2,1),
(1,2,2),
(1,2,4),
(1,4,1),
(1,4,3),
(1,4,4),
(1,5,1),
(1,5,3),
(1,5,5),
(1,6,1),
(1,6,5),
(1,6,6)
Then do the collect:
select
merchant_id,
week_id,
collect_set(acc_id) over (partition by merchant_id ORDER BY week_id RANGE BETWEEN 4 preceding AND 0 preceding) as uniq_accs_prev_4_weeks
from
table_test_test
The result table is :
merchant_id week_id uniq_accs_prev_4_weeks
1 1 0 []
2 1 0 []
3 1 0 []
4 1 2 [9,8,10]
5 1 2 [9,8,10]
6 1 2 [9,8,10]
7 1 4 [9,8,10,1,2,4]
8 1 4 [9,8,10,1,2,4]
9 1 4 [9,8,10,1,2,4]
10 1 5 [1,2,4,3]
11 1 5 [1,2,4,3]
12 1 5 [1,2,4,3]
13 1 6 [1,2,4,3,5]
14 1 6 [1,2,4,3,5]
15 1 6 [1,2,4,3,5]
As you can see, there are redundant rows in the table. This is just an example, in my actual case this table is huge and the redundancy causes memory problem.
I have tried using distinct and group by but neither of these works.
Is there a good way to do it? Thanks a lot.
Distinct works good:
select distinct merchant_id, week_id, uniq_accs_prev_4_weeks
from
(
select
merchant_id,
week_id,
collect_set(acc_id) over (partition by merchant_id ORDER BY week_id RANGE BETWEEN 4 preceding AND current row) as uniq_accs_prev_4_weeks
from
table_test_test
)s;
Result:
OK
1 0 [9,8,10]
1 2 [9,8,10,1,2,4]
1 4 [9,8,10,1,2,4,3]
1 5 [1,2,4,3,5]
1 6 [1,2,4,3,5,6]
Time taken: 98.088 seconds, Fetched: 5 row(s)
My Hive does not accept 0 preceding, I replaced with current row. It seems like this bug or this bug, my Hive version is 1.2. Yours should work fine with distinct added in the upper subquery.

Oracle - some problems with Group Operations

I need your help ... i tryed more time but can't find a soluction (i think that is simple but I have errors in oracle :( :( )
an example:
i have a table with
teams: what team played
gameDate: when played
goalHours: when teamA or teamB do a goal
goalNumber: how much goal are doing in the same hour
endGame: when finish the game
teams gameDate goalHours goalNumber endGame
team01-VS-team02 20110901 21 2 20110902
team01-VS-team02 20110901 22 1 20110902
team01-VS-team02 20110901 23 3 20110902
team03-VS-team02 20110902 18 3 20110905
team03-VS-team02 20110902 19 1 20110905
team04-VS-team02 20110904 06 5 20110906
team01-VS-team02 20110101 18 1 20110902
I need a select with all distinct teamA-VS-teamB the last gameDate
i need for every distinct teamA-VS-teamB, in their last game, the distinct hours of goalHours, the sum of goalNumber, and when stop the game.
something like this:
teams lastGameDate distinctGoalHours sumGoalNumber endGame
team01-VS-team02 20110901 3 6 20110902
team03-VS-team02 20110902 2 4 20110905
team04-VS-team02 20110904 1 5 20110906
i try with:
SELECT teams,
MAX(gameDate),
MAX (endDate),
SUM (goalNumber),
COUNT (DISTINCT goalHours)
FROM myTable
GROUP BY teams
this select doesn't work well because i don't want count
team01-VS-team02 20110101 18 1 20110902, this isn't last game date.
with this select i have 4 distinctGoalHours and 7 sumGoalNumber.
i need a select with
team01-VS-team02 20110901 3 6 20110902
team03-VS-team02 20110902 2 4 20110905
team04-VS-team02 20110904 1 5 20110906
... I hope that i show you all information that you need and thank you very much! :D
Like any other SQL, you need to restrict the result set with the appropriate filter. In your case, you need to use a sub-query to identify the latest gameDate for each team.
There are several different ways of implementing this. Here is one which works:
SQL> SELECT teams,
MAX(gameDate),
MAX (endGame),
SUM (goalNumber),
COUNT (DISTINCT goalHours)
FROM myTable
WHERE (teams, gameDate) IN
( select teams, max(gameDate)
from myTable
GROUP BY teams )
GROUP BY teams
/
2 3 4 5 6 7 8 9 10 11 12
TEAMS MAX(GAMED MAX(ENDGA SUM(GOALNUMBER) COUNT(DISTINCTGOALHOURS)
------------------------------ --------- --------- --------------- ------------------------
team03-VS-team02 02-SEP-11 05-SEP-11 4 2
team01-VS-team02 01-SEP-11 02-SEP-11 6 3
team04-VS-team02 04-SEP-11 06-SEP-11 5 1
SQL>
You need to include the gameDate in the group by. Something like:
SELECT teams
, gameDate
, MAX( endDate )
, SUM( goalNumber )
, COUNT( DISTINCT goalHours )
FROM myTable
GROUP BY teams
, gameDate

Resources