I have a table that tracks mileage of 10 vehicles every hour every day in a oracle database. For example:
Car | Mileage| Timestamp
Honda | 23.4| 11-Jan-17 08.00.00.000000 AM
Honda | 22| 11-Jan-17 09.00.00.000000 AM
Honda | 21.3 | 11-Jan-17 10.00.00.000000 AM
Honda | 24.4| 11-Jan-17 11.00.00.000000 AM
Honda | 23.2| 12-Jan-17 08.00.00.000000 AM
Honda | 25| 12-Jan-17 09.00.00.000000 AM
Honda | 26| 12-Jan-17 10.00.00.000000 AM
I dont understand how I can write a query to run this everyday for last 1 years worth of data and select mileage for every car before 9am everyday
Assuming you mean mileage later than midnight and prior to 09:00 then the following will do the job and also cope with other car makes.
WITH base_data AS
(SELECT car, mileage, read_date , ROW_NUMBER() OVER(PARTITION BY car,TRUNC(READ_DATE) ORDER BY read_date DESC) as ranking
FROM wg_test
WHERE EXTRACT (HOUR FROM read_date) BETWEEN 0 AND 8
AND read_date > SYSDATE - 365)
SELECT car, mileage, read_date
FROM base_data
WHERE ranking = 1
Related
is it possible to create a data model in BI publisher (OTM) that looks at the shipments of:
yesterdays date
today date
tomorrow date
With the exception that on Friday instead of looking at tomorrow we look at next Monday and on Monday instead of looking at yesterday we look at last Friday.
The code that we have so far to look at the shipments for yesterday, today and tomorrow is, but we would like to put in the exception. Can anyone help us with this? thanks in advance for the help!!!
SELECT
S.SHIPMENT_GID SHIPMENT
FROM
SHIPMENT S,
SHIPMENT_INVOLVED_PARTY INV
WHERE
S.PERSPECTIVE = 'B'
AND
S.SHIPMENT_GID = INV.SHIPMENT_GID
AND
INV.INVOLVED_PARTY_QUAL_GID = 'BILL-TO'
AND
INV.INVOLVED_PARTY_CONTACT_GID = 'RSK.50144'
AND
(TRUNC(sysdate)+ 1 = TRUNC(S.START_TIME) OR TRUNC(sysdate) = TRUNC(S.START_TIME) OR TRUNC (sysdate) -1 = TRUNC(S.START_TIME))
You can use a case statement to look 5 days ahead if today is Thursday or Friday, and 3 days ahead the other days.
As there are not expected to be any rows the weekend this should always return 3 days if records.
with days as(
--create 31 days for a month
select sysdate -1 + level AS dt
from dual
connect by level <= 30
)
select
dt,
TO_CHAR( dt, 'D' ) "dayNo",
TO_CHAR( dt, 'day' )"dayName"
from days
where dt <
sysdate +
case when to_char(sysdate,'D')
in ('5','4')then 5
else 3 end
DT | dayNo | dayName
:-------- | :---- | :--------
15-APR-22 | 5 | friday
16-APR-22 | 6 | saturday
17-APR-22 | 7 | sunday
18-APR-22 | 1 | monday
19-APR-22 | 2 | tuesday
db<>fiddle here
Hope am not over thinking this...
I am currently looking for any pointers on this. I have a table/view
|Cust_ID | CName | Inv_Date | Sales
|01A | A | 2/7/2006 | 20
|02A | B | 2/7/2006 | 10
|01A | A | 11/5/2005 | 15
Each customer has very many invoices on various dates
I would then like to extract each customer with sales for
Three (months) of the current year (e.g. 2006). This is 3 months prior to today's date.
Inv_Date >= add_months(trunc(sysdate, 'month'), -3)
and Inv_Date <= add_months(last_day(sysdate), -1)
The same three (3) months of the previous year (2005)?!
Would assume something like
|Cust_ID | CName | CY_Sum_Sales | PY_Sum_Sales
|01A | A | 20 | 15
|02A | B | 0 | 0
Assuming 'sysdate' is 1/8/2008. The following is my trial
select Customer_No, Customer_Name,
TO_CHAR(SUM(Sales_Colmn), 'fm999G999G999G999G999D0') as "TYear_Sale",
TO_CHAR((SELECT SUM(Sales_Colmn) from cust_table CL
where CL.invoice_date BETWEEN add_months(trunc(to_date('&From_Dt', 'DD/MM/YYYY'), 'mm'), -(3 + 12)) --15 months
and add_months(trunc(to_date('&To_Dt', 'DD/MM/YYYY'), 'mm'), -(1 + 12)) --13 months)
and Customer_No = CL.Customer_No), 'fm999G999G999G999G999D0') as "LYear_Sale"
from cust_table
where invoice_date BETWEEN add_months(trunc(to_date('&From_Dt', 'DD/MM/YYYY'), 'mm'), -3) --3 months
and add_months(trunc(to_date('&To_Dt', 'DD/MM/YYYY'), 'mm'), -1) --1 months)
GROUP BY Customer_No, Customer_Name
ORDER BY 3
But it takes too long to run. Must be doing something wrong
Functions (add_months, sysdate) you use suggest this is Oracle.
As you want to go back to same months previous year, you just have to add (OK, subtract) another 12 months. Something like this:
SQL> select trunc(sysdate) c_today,
2 trunc(sysdate, 'mm') c_trunc_today,
3 --
4 add_months(trunc(sysdate, 'mm'), -3) c_3_months_ago,
5 add_months(trunc(sysdate, 'mm'), -1) c_1_month_ago,
6 --
7 add_months(trunc(sysdate, 'mm'), -(3 + 12)) c_15_months_ago,
8 add_months(trunc(sysdate, 'mm'), -(1 + 12)) c_13_months_ago
9 from dual; ^^
this!
C_TODAY C_TRUNC_TO C_3_MONTHS C_1_MONTH_ C_15_MONTH C_13_MONTH
---------- ---------- ---------- ---------- ---------- ----------
03.11.2021 01.11.2021 01.08.2021 01.10.2021 01.08.2020 01.10.2020
--------------------- =====================
this year previous year, same months
SQL>
I have Incoming Stock transaction data using Oracle:
ID | DESCRIPTION | PART_NO | QUANTITY | DATEADDED
TR5 | FG | P0025 | 5 | 06-SEP-2017 08:20:33 <-- just now added
TR4 | Test | TEST1 | 8 | 05-SEP-2017 15:11:15
TR3 | FG | GSDFGSG | 10 | 31-AUG-2017 16:26:04
TR2 | FG | GSDFGSG | 2 | 31-AUG-2017 16:05:39
TR1 | FG | GSDFGSG | 2 | 30-AUG-2017 16:30:16
And now I'm grouping that data to be:
TR_ID | PART_NO | TOTAL
TR1 | GSDFGSG | 14
TR4 | TEST1 | 8
TR5 | P0025 | 5 <-- just now added
Query Code:
SELECT MIN(TRANSACTION_EQUIPMENTID) as TR_ID,
PART_NO,
SUM(T.QUANTITY) AS TOTAL
FROM WA_II_TBL_TR_EQUIPMENT T
GROUP BY T.PART_NO
As you can see on that data and query code, I'm show TR_ID using MIN to get first ID on first transaction.
And now I have Outgoing transaction data:
Assume I try to get quantity 8
ID_FK | QUANTITY
TR1 | 8
And now I want to get last ID due to quantity 8 has been consumed
ID | DESCRIPTION | PART_NO | QUANTITY
TR3| FG | GSDFGSG | 10 <-- CONSUMED 4+2+2, TOTAL 8
TR2| FG | GSDFGSG | 2 <-- CONSUMED 2+2, TOTAL 4
TR1| FG | GSDFGSG | 2 <-- CONSUMED 2
As you can see above, TR1, TR2 has been consumed. Now I want the query
SELECT MIN(TRANSACTION_EQUIPMENTID) as TR_ID,
PART_NO,
SUM(T.QUANTITY) AS TOTAL
FROM WA_II_TBL_TR_EQUIPMENT T
GROUP BY T.PART_NO
get the last id is : TR3, due to TR1 & TR2 has been consumed.
How to do that in query?
Take minimum id where growing sum is greater than 8. Use analytic sum():
select min(id) id
from (select t.*,
sum(quantity) over (partition by part_no order by id) sq
from t
where part_no = 'GSDFGSG'
)
where sq >= 8
Test data, output:
create table t(ID varchar2(3), DESCRIPTION varchar2(5),
PART_NO varchar2(8), QUANTITY number(5), DATEADDED date);
insert into t values ('TR4', 'Test', 'TEST1', 8, timestamp '2017-09-05 15:11:15');
insert into t values ('TR3', 'FG', 'GSDFGSG', 10, timestamp '2017-08-31 16:26:04');
insert into t values ('TR2', 'FG', 'GSDFGSG', 2, timestamp '2017-08-31 16:05:39');
insert into t values ('TR1', 'FG', 'GSDFGSG', 2, timestamp '2017-08-30 16:30:16');
insert into t values ('TR5', 'FG', 'GSDFGSG', 3, timestamp '2017-08-31 17:00:00');
Edit:
Add part_no and total columns and group by clause:
select min(id) id, part_no, min(sq) total
from (select t.*,
sum(quantity) over (partition by part_no order by id) sq
from t
where part_no = 'GSDFGSG'
)
where sq >= 8
group by part_no
ID PART_NO TOTAL
--- -------- ----------
TR3 GSDFGSG 14
I have a table in an Oracle 11g database that looks like this:
ownerid | propertyid | name
--------------------------------------
1 | 1000001 | SMITH MARY
2 | 1000001 | SMITH JOHN
3 | 1000002 | HUGHES JANE
4 | 1000003 | CHEN ALICE
5 | 1000003 | MCCOY ELLIS
I'm trying to group the table on propertyid and pivot the rows to columns so that it looks like this:
propertyid | owner1 | owner2
---------------------------------------------
10001 | SMITH MARY | SMITH JOHN
10002 | HUGHES JANE | <null>
10003 | CHEN ALICE | MCCOY ELLIS
Each property can have between 1 and 3 owners, but I'm only interested in the first two as they appear when ordered on ownerid.
My best solution was to create two subqueries: one of "first" owners and another "second" owners. I used the nth_value function as follows:
-- first owners
select
propertyid,
nth_value(name, 1) over (partition by propertyid order by ownerid) as owner_1
from owners
But this gives me duplicate (although correct) pairs of properties and owners if the total number of owners is greater than 1. In general I feel like there must be a better way of doing this. Does anyone have any ideas?
with
inputs ( ownerid, propertyid, name ) as (
select 1, 1000001, 'SMITH MARY' from dual union all
select 2, 1000001, 'SMITH JOHN' from dual union all
select 3, 1000002, 'HUGHES JANE' from dual union all
select 4, 1000003, 'CHEN ALICE' from dual union all
select 5, 1000003, 'MCCOY ELLIS' from dual
),
prep ( propertyid, name, rn ) as (
select propertyid, name,
row_number() over (partition by propertyid order by ownerid)
from inputs
)
select *
from prep
pivot (max(name) for rn in (1 as owner1, 2 as owner2))
order by propertyid
;
PROPERTYID OWNER1 OWNER2
---------- ----------- -----------
1000001 SMITH MARY SMITH JOHN
1000002 HUGHES JANE
1000003 CHEN ALICE MCCOY ELLIS
3 rows selected.
Example data (complete table has more columns and millions of rows):
invoice_number |year |department |euros
-------------------------------------------------------------
1234 |2010 |1 | 200
1234 |2011 |1 | 200
1234 |2011 |2 | 200
4567 |2010 |1 | 450
4567 |2010 |2 | 450
4567 |2010 |3 | 450
My Objective:
I want to sum the euros for every year and every department in every possible combination.
How result should look:
year |department |euros
--------------------------------------------
2010 |1 |650
2010 |2 |450
2010 |3 |450
2010 |(null) |650
2011 |1 |200
2011 |2 |200
(null) |1 |650
(null) |2 |650
(null) |3 |450
(null) |(null) |650
My query:
select year
, department
, sum(euros)
from table1
group by cube (
year
, department
)
Problem:
One invoice number can occur in several categories. For example, one invoice can have items from 2010 and 2011. This is no problem when I want to show the data per year. However, when I want the total over all years the euros will be summed twice, one time for each year. I want the functionality of 'group by cube' but I want to sum only distinct invoice numbers for aggregations.
Problem table:
year |department |euros
--------------------------------------------
2010 |1 |650
2010 |2 |450
2010 |3 |450
2010 |(null) |1550
2011 |1 |200
2011 |2 |200
(null) |1 |850
(null) |2 |650
(null) |3 |450
(null) |(null) |1950
Is it possible to do what I want? So far my search has yielded no results. I have created a SQL Fiddle, I hope it works
[Removed previous "solution"]
New attempt: here is quite an ugly solution, but it seems to work, even when two invoices have the same amount. With two table accesses, you should check if performance is acceptable.
SQL> with table1_cubed as
2 ( select year
3 , department
4 , grouping_id(year,department) gid
5 from table1
6 group by cube(year,department)
7 )
8 , join_distinct_invoices as
9 ( select distinct x.*
10 , r.invoice_number
11 , r.euros
12 from table1_cubed x
13 inner join table1 r on (nvl(x.year,r.year) = r.year and nvl(x.department,r.department) = r.department)
14 )
15 select year
16 , department
17 , sum(euros)
18 from join_distinct_invoices
19 group by year
20 , department
21 , gid
22 order by year
23 , department
24 /
YEAR DEPARTMENT SUM(EUROS)
---------- -------------------- ----------
2010 1 650
2010 2 450
2010 3 450
2010 650
2011 1 200
2011 2 200
2011 200
1 650
2 650
3 450
650
11 rows selected.
select year
,department
,case when GROUPING_id(year,department) in (3) then sum(dist_euro) else sum(euros) end sums
,decode(GROUPING_id(year,department),0,'NO GROUP',1,'DEPARTMENT IS NULL',2,'YEAR IS NULL',3,'TOTAL OVER ALL YEARS') info
from (
select year
, department
, euros
,case when row_number() over(partition by year order by year) = 1 then euros else 0 end dist_euro
from table1)
group by cube (
year
, department
)
order by GROUPING_id(year,department)