Oracle: Returning the earliest date - oracle

I have a stored procedure which I use to return the earliest available date in a column of dates. I need to only return the earliest, and currently am using date arithmetic to reduce the number of returned rows. However, doing it this way, my procedure gets stuck in a loop of the first two top returned values, meaning I have several rows which are never read. Could somebody please let me know where I need to use the MIN function in the following WHERE clause, please? Thanks:
SELECT **COLS**
INTO **VARS**
FROM **TABLE**
INNER JOIN **TABLE TO JOIN**
ON **JOIN TARGET**
WHERE ROWNUM = 1 AND LASTREADTIME < SYSDATE - (30/86400)
ORDER BY LASTREADTIME DESC;

if you only need the earliest date
SELECT MIN(LastReadTime)
INTO **VARS**
FROM table
if you need other datas
SELECT t2.col1, t1.col1, t1.col2, t1.LastTreadTime
INTO **VARS**
FROM table t1
JOIN table2 t2 on t1.col1 = t2.col1
WHERE t1.LastReadTime = (SELECT MIN(t2.LastReadTime) FROM table t2);

Related

How to select data from multiple row into one row with multiple column dynamically?

I am trying to select multiple rows of data into one row through multiple columns which will change dynamically.
This is in Oracle database. I want to count repeated work done by the LEAD_TECHNISIAN_ID within a duration. If the difference of last work delivery date and new work receive date is 15 or below 15 then LEAD_TECHNISIAN_ID has one repeated work.
List item
SELECT *
FROM (WITH CTE AS (
SELECT ROW_NUMBER () OVER (ORDER BY ID) AS RW,
RECEIVED_DATE,
DELIVERY_DATE,
SERVICE_NO,
LEAD_TECHNISIAN_ID,
ID,
SERVICE_CENTER
FROM ( SELECT cc.SERVICE_CENTER,
CC.ID,
CC.BARCODE,
TRUNC (cc.CREATED_DATE) RECEIVED_DATE,
TRUNC (CC.DELIVERY_DATE) DELIVERY_DATE,
cc.SERVICE_NO,
CC.LEAD_TECHNISIAN_ID
FROM customer_complains cc
WHERE cc.BARCODE IN (SELECT BARCODE
FROM (SELECT BARCODE,
COUNT (BARCODE)
FROM customer_complains c
WHERE c.BARCODE <> 'UNDEFINE'
AND C.BARCODE = NVL ('351950102757821', BARCODE)
AND c.SEGMENT3 = NVL ('',c.SEGMENT3)
AND c.SEGMENT3 IN (SELECT SEGMENT3
FROM ITEM_MST
WHERE PRODUCT_GROUP = NVL ('',PRODUCT_GROUP))
GROUP BY c.BARCODE
HAVING COUNT (c.BARCODE) >1))
ORDER BY ID DESC)
ORDER BY ID DESC)
SELECT a.id,
a.DELIVERY_DATE,
a.RECEIVED_DATE,
b.RECEIVED_DATE PRE_RCV,
b.DELIVERY_DATE PRE_DEL,
(a.RECEIVED_DATE - b.DELIVERY_DATE) AS DIFF,
a.SERVICE_NO,
a.LEAD_TECHNISIAN_ID,
b.LEAD_TECHNISIAN_ID PRE_TECH --, a.DELIVERY_DATE
FROM CTE a
LEFT JOIN CTE b ON a.RW = b.RW + 1
)
WHERE DIFF <= 15
Here is the output for a specific barcode. but when I try for All the barcode I have in My Customer_complains table. The query provides irrelevant output.
Currently your code is giving numbers 1,2,3,4... to rows irrespective of LEAD_TECHNISIAN_ID and then you are joining it with RW. It will not consider LEAD_TECHNISIAN_ID while giving row numbers.
RW must start with 1 for each LEAD_TECHNISIAN_ID.
You just need to change calculation of RW as following:
ROW_NUMBER () OVER (PARTITION BY LEAD_TECHNISIAN_ID ORDER BY ID) AS RW
Cheers!!

Oracle DB query to get records count and calculate average afterward

Could anyone please help me regarding that Oracle query.
Here is my required output.
Thanks in advanced.from below query return some record i want to Calculate
Average means SUM(COST+DURATION)/No.of row return form that query but below query doing partition based on SITE_ID i dont want any partition,What is want is whatever query return (Sum of all Duration+sum of all Cost/No. of row returns)but without any partition is that any way i can do that
select * from (
SELECT ROW_NUMBER() OVER (ORDER BY 1) RN,
SITE_ID,
CASEID,
WOID,
DURATION,
COST,
(SUM(COST+DURATION) OVER(PARTITION BY SITE_ID))/COUNT as TotalCost from
(
SELECT COUNT(*) OVER () as COUNT,
SITE_ID,
CASEID,
WOID,
ROUND(table1.duration/3600,2) AS DURATION,
ROUND(table2.duration/3600),2) AS COST
FROM table1 ) AVG
WHERE (1=1)
)
where rn between 0 and 1000
On the basis of your revised question what I think you want is the total of COST and DURATION for each SITE, plus an average of these figures derived from the number of entries in table1 and table2. This is what this query does:
select site_id
, duration
, cost
, (duration+cost)/no_of as avg_total_cost
from (
select
table1.site_id
, count(*) as no_of
, sum(round(table1.duration/3600,2)) as duration
, sum(round((table1.labor_rate * table2.duration)/3600,2)) as cost
from table1
inner join table2
on table1.id = table2.id
group by table1.site_id
)
/
Here is a SQL Fiddle demo to prove that this query runs successfully.
Your question appears to reference other tables, site and emp, which I have ignored because you don't provide join conditions for them. Likewise I have ignored the top-n filter; you can add it back it if you want.

Converting rownum from Oracle to Postgres

I need to make a conversion from Oracle SQL to PostgreSQL.
select * from table1 inner join table2 on table1.id = table2.table1Id
where table1.col1 = 'TEST'
and rownum <=5
order by table2.col1
If I delete and rownum <=5 and put at the end limit 5, there are differences between the 2 dialects. In Oracle, first are selected the 5 elements, and after that, they are sorted by table2.col1 . In Postgres, first all the list is sorted, and AFTER there are selected the first 5 elements.
How can I obtain the same result in Postgres as in Oracle?
Thanks!
To get the behavior you desire, you can use a subquery like this:
SELECT * FROM (
SELECT table1.col1 as t1col1, table2.col1 as t2col1
FROM table1 INNER JOIN table2 ON table1.id = table2.table1Id
WHERE table1.col1 = 'TEST'
LIMIT 5
) AS sub
ORDER BY t2col1;
I named the columns there because in your example both tables had a col1.
Note however that without any ordering on the inner query, the selection of 5 rows you get will be purely random and subject to change.
Depending on the version you are using, PostgreSQL 8.4 and above have Window functions. Window function ROW_NUMBER() is capable of implementing the functionality of Oracle pseudo column rownum.
select row_number() over() as rownum,* from table1 inner join table2 on table1.id = table2.table1Id where table1.col1 = 'TEST' and rownum <=5 order by table2.col1;

Oracle query taking too much of time when I use rownum

If I execute below query, it is returning results very fast.
(select * from
select * from t1, t2 t3, t4 where ...(inner/outer join) group by ...) order by create_date desc)
How ever If I use ROWNUM like below, it is taking too much of time.
select * from (select * from
select * from t1, t2 t3, t4 where ...(inner/outer join) group by ...) order by create_date desc) where rownum =1
could you please let me know why t is taking too much of time. How I can get latest date record.
Are you see all returning results for first query or are you see first few rows and you don't wait last row?
I think in second query, first works internal query and after the condition "rownum =1" check all result records

Counting rows by a condition in another table

Need to count the number of rows in one table which connect to a second table by (name.sample) where in the second table the (name.sample) was created before (or after) a certain date.
select count(*) from table1 t1
inner join table2 t2 on t1.my_foreign_key_column = t2.my_primary_key_column
where t2.creation_date >= 'my_date_literal'

Resources