I have several by number of dates and against them quantity.
the goal is to total the quantity and show only the minimum date
date quantity
13-SEP-15 5
16-FEB-20 6
16-FEB-21 100
expected result;
date quantity
13-SEP-15 111
It's just two aggregates, nothing else.
Sample data:
SQL> with test (datum, quantity) as
2 (select date '2015-09-13', 5 from dual union all
3 select date '2020-02-16', 6 from dual union all
4 select date '2021-02-16', 100 from dual
5 )
Query:
6 select min(datum) min_datum,
7 sum(quantity) total
8 from test;
MIN_DATUM TOTAL
--------- ----------
13-SEP-15 111
SQL>
Related
This question already has answers here:
Second highest grade for each student
(3 answers)
Closed 3 months ago.
My data looks like below:
table
REF_NUM ID DATE
SIM1 1 12-Oct-22
SIM1 2 10-Oct-22
SIM2 3 15-Oct-22
SIM2 4 14-Oct-22
SIM3 5 08-Oct-22
SIM3 6 02-Oct-22
SIM4 7 08-Oct-22
SIM4 8 10-Oct-22
Output should be as below:
Output:
REF_NUM ID DATE
SIM1 2 10-Oct-22
SIM2 4 14-Oct-22
SIM3 6 02-Oct-22
SIM4 7 08-Oct-22
basically I need data with distinct ref_num , respective ID and with SECOND HIGHEST DATE. Here I have just given two dates in main table, But each ref_num can have more than two dates.
I can sure that whatever I have tried is wrong
Rank rows per each ref_num by the date datatype value in descending order; then fetch these that rank as the second highest.
Sample data:
SQL> with test (ref_num, id, datum) as
2 (select 'sim1', 1, date '2022-10-12' from dual union all
3 select 'sim1', 2, date '2022-10-10' from dual union all
4 select 'sim2', 3, date '2022-10-15' from dual union all
5 select 'sim2', 4, date '2022-10-14' from dual union all
6 select 'sim3', 5, date '2022-10-08' from dual union all
7 select 'sim3', 6, date '2022-10-02' from dual union all
8 select 'sim4', 7, date '2022-10-08' from dual union all
9 select 'sim4', 8, date '2022-10-10' from dual
10 ),
Query begins here:
11 temp as
12 (select ref_num, id, datum,
13 rank() over (partition by ref_num order by datum desc) rnk
14 from test
15 )
16 select ref_num, id, datum
17 from temp
18 where rnk = 2
19 order by ref_num;
REF_ ID DATUM
---- ---------- ----------
sim1 2 10.10.2022
sim2 4 14.10.2022
sim3 6 02.10.2022
sim4 7 08.10.2022
SQL>
I have the following table showing when customers bought a certain product. The data I have is CustomerID, Amount, Dat. I am trying to create the column ProductsIn30Days, which represents how many products a customer bought in the range Dat-30 days inclusive the current day.
For example, ProductsIn30Days for CustomerID 1 on Dat 25.3.2020 is 7, since the customer bought 2 products on 25.3.2020 and 5 more products on 24.3.2020, which falls within 30 days before 25.3.2020.
CustomerID
Amount
Dat
ProductsIn30Days
1
1
23.3.2018
1
1
2
24.3.2020
2
1
3
24.3.2020
5
1
2
25.3.2020
7
1
2
24.5.2020
2
1
1
15.6.2020
3
2
7
24.3.2017
7
2
2
24.3.2020
2
I tried something like this with no success, since the partition only works on a single date rather than on a range like I would need:
select CustomerID, Amount, Dat,
sum(Amount) over (partition by CustomerID, Dat-30)
from table
Thank you for help.
You can use an analytic SUM function with a range window:
SELECT t.*,
SUM(Amount) OVER (
PARTITION BY CustomerID
ORDER BY Dat
RANGE BETWEEN INTERVAL '30' DAY PRECEDING AND CURRENT ROW
) AS ProductsIn30Days
FROM table_name t;
Which, for the sample data:
CREATE TABLE table_name (CustomerID, Amount, Dat) AS
SELECT 1, 1, DATE '2018-03-23' FROM DUAL UNION ALL
SELECT 1, 2, DATE '2020-03-24' FROM DUAL UNION ALL
SELECT 1, 3, DATE '2020-03-24' FROM DUAL UNION ALL
SELECT 1, 2, DATE '2020-03-25' FROM DUAL UNION ALL
SELECT 1, 2, DATE '2020-05-24' FROM DUAL UNION ALL
SELECT 1, 1, DATE '2020-06-15' FROM DUAL UNION ALL
SELECT 2, 7, DATE '2017-03-24' FROM DUAL UNION ALL
SELECT 2, 2, DATE '2020-03-24' FROM DUAL;
Outputs:
CUSTOMERID
AMOUNT
DAT
PRODUCTSIN30DAYS
1
1
2018-03-23 00:00:00
1
1
2
2020-03-24 00:00:00
5
1
3
2020-03-24 00:00:00
5
1
2
2020-03-25 00:00:00
7
1
2
2020-05-24 00:00:00
2
1
1
2020-06-15 00:00:00
3
2
7
2017-03-24 00:00:00
7
2
2
2020-03-24 00:00:00
2
Note: If you have values on the same date then they will be tied in the order and always aggregated together (i.e. rows 2 & 3). If you want them to be aggregated separately then you need to order by something else to break the ties but that would not work with a RANGE window.
db<>fiddle here
An image of the Discharge date and admission date in which i am supposed to subtract as (discharge date – admitted
date) +1 .
As you said - subtract and sum. Sample data in lines #1 - 5, query begins at line #6.
SQL> with test (who, admission_date, discharge_date) as
2 (select 'Leslie', date '2010-09-13', date '2010-09-25' from dual union all
3 select 'Leslie', date '2014-09-03', date '2014-09-21' from dual union all
4 select 'Leslie', date '2015-12-03', date '2015-12-14' from dual
5 )
6 select who, sum(discharge_date - admission_date + 1) total_days
7 from test
8 group by who;
WHO TOTAL_DAYS
------ ----------
Leslie 44
SQL>
Basically I have Product table like this:
date price
--------- -----
02-SEP-14 50
03-SEP-14 60
04-SEP-14 60
05-SEP-14 60
07-SEP-14 71
08-SEP-14 45
09-SEP-14 45
10-SEP-14 24
11-SEP-14 60
I need to update the table in this form
date price id
--------- ----- --
02-SEP-14 50 1
03-SEP-14 60 2
04-SEP-14 60 2
05-SEP-14 60 2
07-SEP-14 71 3
08-SEP-14 45 4
09-SEP-14 45 4
10-SEP-14 24 5
11-SEP-14 60 6
What I have tried:
CREATE SEQUENCE user_id_seq
START WITH 1
INCREMENT BY 1
CACHE 20;
ALTER TABLE Product
ADD (ID number);
UPDATE Product SET ID = user_id_seq.nextval;
This is updating the ID in the usual way like 1,2,3,4,5..
I have no idea how to do it using basic SQL commands. Please suggest how can I make it. Thank you in advance.
Here is one way to create a view from your base data. I assume you have more than one product (identified by product id), and that the price dates aren't necessarily consecutive. The sequence is separate for each product id. (Also, product should be the name of a different table - where the product id is primary key, and you have other information such as product name, category, etc. The table in your post would be more properly called something like price_history.)
alter session set nls_date_format='dd-MON-rr';
create table product ( prod_id number, dt date, price number );
insert into product ( prod_id, dt, price )
select 101, '02-SEP-14', 50 from dual union all
select 101, '03-SEP-14', 60 from dual union all
select 101, '04-SEP-14', 60 from dual union all
select 101, '05-SEP-14', 60 from dual union all
select 101, '07-SEP-14', 71 from dual union all
select 101, '08-SEP-14', 45 from dual union all
select 101, '09-SEP-14', 45 from dual union all
select 101, '10-SEP-14', 24 from dual union all
select 101, '11-SEP-14', 60 from dual union all
select 102, '02-SEP-14', 45 from dual union all
select 102, '04-SEP-14', 45 from dual union all
select 102, '05-SEP-14', 60 from dual union all
select 102, '06-SEP-14', 50 from dual union all
select 102, '09-SEP-14', 60 from dual
;
commit;
create view product_vw ( prod_id, dt, price, seq ) as
select prod_id, dt, price,
count(flag) over (partition by prod_id order by dt)
from ( select prod_id, dt, price,
case when price = lag(price) over (partition by prod_id order by dt)
then null else 1 end as flag
from product
)
;
Now check what the view looks like:
select * from product_vw;
PROD_ID DT PRICE SEQ
------- ------------------- ---------- ----------
101 02/09/0014 00:00:00 50 1
101 03/09/0014 00:00:00 60 2
101 04/09/0014 00:00:00 60 2
101 05/09/0014 00:00:00 60 2
101 07/09/0014 00:00:00 71 3
101 08/09/0014 00:00:00 45 4
101 09/09/0014 00:00:00 45 4
101 10/09/0014 00:00:00 24 5
101 11/09/0014 00:00:00 60 6
102 02/09/0014 00:00:00 45 1
102 04/09/0014 00:00:00 45 1
102 05/09/0014 00:00:00 60 2
102 06/09/0014 00:00:00 50 3
102 09/09/0014 00:00:00 60 4
NOTE: This answers the question that was originally asked. The OP changed the data.
If your data is not too large, you can use a correlated subquery:
update product p
set id = (select count(distinct p2.price)
from product p2
where p2.date <= p.date
);
If your data is larger, then merge is more appropriate.
WITH cts AS
(
SELECT row_number() over (partition by price order by price ) as id
,date
,price
FROM Product
)
UPDATE p
set p.id = cts.id
from product p join cts on cts.id = p.id
This is the best way by which you try to do.
There is no another simple way to do this using simple statements
Guys i have a table called A which has columns as
-----
A
-----
S_DATE
DUR
VIEWS
AMOUNT
The data in the table A has the following rows which is DateWise.
20101023 12 1 10000.0
20101101 2 4 200.0
20101114 4 5 -9
20101201 6 10 150.0
20101219 1 12 130.0
My requirement is that i want to write an SQL query that does monthwise *report*. For example from webGUI , when i select on the dropdown for month as DEC and select year as 2010 . I need to create show the sum of DUR,VIEWS and AMOUNT from 1st of November 2010 to 1st of December 2010.Any Ideas on how to do it.
The result for DEC2010 should be like below
**DEC2010 12 19 341**
this would work (although of course due to your requirement the first day of november will be in both the november and december monthly reports ?!):
SQL> VARIABLE p_months VARCHAR2(3);
SQL> VARIABLE p_year NUMBER;
SQL> EXEC :p_months := 'DEC'; :p_year := 2010;
PL/SQL procedure successfully completed.
SQL> WITH tableA AS (
2 SELECT DATE '2010-10-23's_date , 12 dur, 1 views, 10000.0 amount FROM DUAL
3 UNION ALL SELECT DATE '2010-11-01', 2, 4 , 200.0 FROM DUAL
4 UNION ALL SELECT DATE '2010-11-14', 4, 5 , -9 FROM DUAL
5 UNION ALL SELECT DATE '2010-12-01', 6, 10, 150.0 FROM DUAL
6 UNION ALL SELECT DATE '2010-12-19', 1, 12, 130.0 FROM DUAL
7 )
8 SELECT :p_months||:p_year month,
9 SUM(dur),
10 SUM(views),
11 SUM(amount)
12 FROM tableA
13 WHERE s_date >= add_months(to_date(:p_months||:p_year, 'MONYYYY'), -1)
14 AND s_date < to_date(:p_months||:p_year, 'MONYYYY') + 1;
MONTH SUM(DUR) SUM(VIEWS) SUM(AMOUNT)
---------- ---------- ---------- -----------
DEC2010 12 19 341