I want to group by lead function by two column. Here is my table data.
Id Name_Id Name Item_Id Item_Name date
1 1 Car 1 SUV 1-Jan-2015
2 1 Car 1 SUV 12-March-2015
3 1 Car 1 SUV 20-April-2015
4 1 Car 2 Sport 23-April-2015
5 2 Bike 1 SUV 18-July-2015
6 2 Bike 1 SUV 20-Aug-2015
7 2 Bike 2 Sport 18-Sept-2015
8 2 Bike 3 Honda 20-OCT-2015
And I need result from above table like.
Id Name_Id Name Item_Id Item_Name start date end date
1 1 Car 1 SUV 1-Jan-2015 20-April-2015
2 1 Car 2 Sport 20-April-2015 23-April-2015
3 2 Bike 1 SUV 18-July-2015 20-Aug-2015
4 2 Bike 2 Sport 20-Aug-2015 18-Sept-2015
5 2 Bike 3 Honda 18-Sept-2015 20-OCT-2015
Any suggestion really appreciated.
I don't think you need to use LEAD here. The CTE below computes, for each Item_Id, the earliest and latest date. This is then joined to your original table to restrict to records corresponding to the earliest Item_Id. At the same time, the end date is also pulled in during the join.
WITH cte AS (
SELECT Name,
Item_Id,
MIN(date) AS start_date,
MAX(date) AS end_date
FROM yourTable
GROUP BY Name, Item_Id
)
SELECT t1.Id, t1.Name_Id, t1.Name, t1.Item_Id, t1.Item_Name,
t2.start_date,
t2.end_date
FROM yourTable t1
INNER JOIN cte t2
ON t1.Item_Id = t2.Item_Id AND
t1.Name = t2.Name AND
t1.date = t2.start_date
Related
In PL SQL is there a way to produce the Order Count per customer as follows... Thanks for your help.
Cust Order# Order Count
ABC1 011 1
ABC1 052 2
ABC1 199 3
BBA1 150 1
BBA1 158 2
Thanks
Gavin
If I understood you correctly, a little bit of analytics might do the job. Here's an example:
SQL> with test (cust, order#) as
2 (select 'ABC1', '011' from dual union all
3 select 'ABC1', '052' from dual union all
4 select 'ABC1', '199' from dual union all
5 select 'BBA1', '150' from dual union all
6 select 'BBA1', '158' from dual
7 )
8 select cust, order#,
9 row_number() over (partition by cust order by order#) order_count
10 from test;
CUST ORD ORDER_COUNT
---- --- -----------
ABC1 011 1
ABC1 052 2
ABC1 199 3
BBA1 150 1
BBA1 158 2
SQL>
sounds like you want a GROUP BY such as
select cust, SUM(order_count)
from MyTable
group by cust;
which should yield
cust SUM
ABC1 6
BBA1 3
list days appearing in reservation where only red
boats have been reserved using COUNT aggregate function.
Here is the table
servant table:
sname rating
Joe 4
Bob 2
Tim 9
Mike 1
Lewis 5
boat table:
bname color rating
Ace orange 6
Bethany red 5
Cruiser green 9
WindySea red 8
reservation table:
sname bname day
Bob Ace Monday
Bob Bethany Wednesday
Bob WindySea Saturday
Tim Ace Sunday
Tim Bethany Wednesday
Tim Cruiser Wednesday
Mike Ace Monday
SELECT r.day
FROM reservation r
JOIN boat b
ON r.bname = b.bname
GROUP BY r.day
HAVING COUNT(CASE WHEN b.color <> 'red' THEN 1 ELSE NULL END) = 0
AND COUNT(CASE WHEN b.color = 'red' THEN 1 ELSE NULL END) > 0 -- optional
This has been touched on before on this website. I want distinct on group but I also want to get the other fields too. what I need is the lowest id of each group, but instead I get the highest. I've tried variod SQL queries and the nearest 2 that work are
1)
select *
from reminder
group by Eventgroup
order by autoid
2)
SELECT distinct Autoid,EventDate,Subject,birthdate,Eventgroup
from reminder
group by Eventgroup
order by autoid
Data:
EventDate Subject birthdate Eventgroup autoid
09/10/2017 Joes Birthday 09/10/1995 4 9
13/07/2017 Bill Birthday 13/07/1999 2 8
04/04/2017 Tony Birthday 04/04/1993 3 7
09/10/2016 Joes Birthday 09/10/1995 4 6
13/07/2016 Bill Birthday 13/07/1999 2 5
04/04/2016 Tony Birthday 04/04/1993 3 4
09/10/2015 Joes Birthday 09/10/1995 4 3
13/07/2015 Bill Birthday 13/07/1999 2 2
04/04/2015 Tony Birthday 04/04/1993 3 1
both of these queries return
09/10/2017 Joes Birthday 09/10/1995 4 9
13/07/2017 Bill Birthday 13/07/1999 2 8
04/04/2017 Tony Birthday 04/04/1993 3 7
what I want is the earliets dates such as
09/10/2015 Joes Birthday 09/10/1995 4 3
13/07/2015 Bill Birthday 13/07/1999 2 2
04/04/2015 Tony Birthday 04/04/1993 3 1
Join the table with a subquery that finds the earliest date for each event group.
SELECT a.*
FROM reminders a
JOIN (SELECT eventgroup, MIN(eventdate) mindate
FROM reminders
GROUP BY eventgroup) b
ON a.eventgroup = b.eventgroup AND a.eventdate = b.mindate
This is the same structure as the second query in this answer in the duplicate question.
DEMO
Suppose I have an employee table “DB_EMPLOYEE” with the following values for EMPID and NAME
EMPID NAME
0 Bob
1 Joe
2 Carl
3 Wendy
Next, I have another table listing audits, “ICQA_AUDITS” with the following values for the columns RECORD_ID, AUDITOR_ID, PACKER_ID, SHIPPER_ID
RECORD_ID AUDITOR_ID PACKER_ID SHIPPER_ID
0 0 1 3
1 1 2 3
2 3 1 2
I can write the following query to get the list of audits with the auditor name substituted for the AUDITOR_ID:
SELECT
emp.NAME,
aud.PACKER_ID,
aud.SHIPPER_ID
FROM
ICQA_AUDITS aud, DB_EMPLOYEE emp
WHERE
aud.AUDITOR_ID = emp.EMPID
The formatted output would look something like this:
RECORD_ID NAME PACKER_ID SHIPPER_ID
0 Bob 1 3
1 Joe 2 3
2 Wendy 1 2
My question is this: How might I also get the PACKER_ID and SHIPPER_ID replaced by the appropriate names? Desired output would be the following:
RECORD_ID NAME PACKER_ID SHIPPER_ID
0 Bob Joe Wendy
1 Joe Carl Wendy
2 Wendy Joe Carl
I'm trying to format a report region in APEX and I'm not seeing the easy way to do this. Any help will be much appreciated.
Thanks!
Edit
Expanded example: Suppose that instead of just having one NAME attribute, the DB_EMPLOYEE table has FIRSTNAME and LASTNAME, as follows:
EMPID FIRSTNAME LASTNAME
0 Bob Bobbington
1 Joe Josephson
2 Carl Carlton
3 Wendy Van Dorfenstein
I can write the example query as:
SELECT
emp.LASTNAME || ', ' || emp.FIRSTNAME as "Auditor Name",
aud.PACKER_ID,
aud.SHIPPER_ID
FROM
ICQA_AUDITS aud, DB_EMPLOYEE emp
WHERE
aud.AUDITOR_ID = emp.EMPID
The output would then be:
RECORD_ID Auditor Name PACKER_ID SHIPPER_ID
0 Bobbington, Bob 1 3
1 Josephson, Joe 2 3
2 Van Dorfenstein, Wendy 1 2
The desired output would then be:
Record Auditor Name Packer Name Shipper Name
0 Bobbington, Bob Josephson, Joe Van Dorfenstein, Wendy
1 Josephson, Joe Carlton, Carl Van Dorfenstein, Wendy
2 Van Dorfenstein, Wendy Josephson, Joe Carlton, Carl
Try this query:
SELECT
a.RECORD_ID as id,
b.name as auditor_name,
c.name as packer_name,
d.name as shiper_name
FROM ICQA_AUDITS a
LEFT JOIN DB_EMPLOYEE b ON b.EMPID = a.AUDITOR_ID
LEFT JOIN DB_EMPLOYEE c ON c.EMPID = a.PACKER_ID
LEFT JOIN DB_EMPLOYEE d ON d.EMPID = a.SHIPPER_ID
WHERE a.RECORD_ID = 1
The response must be like this:
id auditor_name packer_name shiper_name
1 Joe Carl Wendy
Change "WHERE" statement to your needs. Good luck.
I want to join my CHEESE table with FRESHNESS to get CHEESE and FRESHNESS code for
cheeses where max(seq_no) for each cheese id is MOLD.
When using rank(), where do I join to FRESHNESS?
CHEESE FRESHNESS
CHEESE_ID SEQ_NO FRESH_CODE FRESH_CODE FRESH_DESC
================================= ========================
1 1 MOLD MOLD MOLDY CHEESE
1 23 FRSH FRSH EDIBLE
1 34 FRSH
2 2 FRSH
2 18 MOLD
3 3 MOLD
3 5 MOLD
3 7 MOLD
DESIRED RESULT
==========================
CHEESE_ID SEQ_NO FRESH_CODE FRESH_DESC SEQ_RANK
2 18 MOLD MOLDY CHEESE 1
3 7 MOLD MOLDY CHEESE 1
Here's my code I'm using to get the desired sequence numbers.
select
cheese_id,seq_no,fresh_code,seq_rank
from ( select
cheese_id,seq_no, fresh_code,
rank() over (partition by cheese_id
order by seq_no desc) seq_rank
from cheese
where seq_rank = 1
and fresh_code = 'MOLD'
You can either do the join in the subquery
select cheese_id,seq_no,fresh_code,fresh_desc,seq_rank
from ( select cheese_id,
seq_no,
fresh_code,
fresh_desc,
rank() over (partition by cheese_id
order by seq_no desc) seq_rank
from cheese
join freshness using (fresh_code) )
where seq_rank = 1
and fresh_code = 'MOLD'
or you can join to your subquery
select cheese_id,seq_no,fresh_code,fresh_desc,seq_rank
from ( select cheese_id,
seq_no,
fresh_code,
fresh_desc,
rank() over (partition by cheese_id
order by seq_no desc) seq_rank
from cheese ) cheese_outer
join freshness using (fresh_code)
where seq_rank = 1
and fresh_code = 'MOLD'