If this is your first visit, be sure to check out the FAQ by clicking the link above. You may have to register before you can post: click the register link above to proceed. To start viewing messages, select the forum that you want to visit from the selection below.

 
Go Back  dBforums > Database Server Software > DB2 > SQL Question

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
  #1 (permalink)  
Old 07-13-09, 15:08
db2udbgirl db2udbgirl is offline
Registered User
 
Join Date: Mar 2006
Location: Tuticorin, India
Posts: 100
SQL Question

DB2 9.1/AIX 5.3
Assuming a table has 3 columns and sample data is as below

Time Name Location
---------- ------ --------
02:03:02 Alan AFRICA
04:03:02 Alan ASIA
05:03:02 Alan NA
07:27:48 Alan ASIA
01:09:10 Tom EUROPE
02:09:10 Tom ASIA
05:09:10 Tom AUS
12:09:10 Tom AFRICA
15:09:10 Tom AUS
05:06:58 Nancy AFRICA
08:06:58 Nancy ASIA
12:06:58 Nancy NA
15:06:58 Nancy AFRICA
17:33:06 Mike EUROPE

I want the following as output from a select statement
Time Name Location
---------- ------ --------
07:27:48 Alan ASIA
15:09:10 Tom AUS
15:06:58 Nancy AFRICA
17:33:06 Mike EUROPE

If I need just Time & Name I can do select max(time), name from xxx group by name. How to code this? Pls advice
Reply With Quote
  #2 (permalink)  
Old 07-13-09, 16:03
n_i n_i is offline
:-)
 
Join Date: Jun 2003
Location: Toronto, Canada
Posts: 4,449
Use a correlated subquery:
Code:
select
...
from table t1
where t1.time = (select max(time) from table1 where user=t1.user)
Reply With Quote
  #3 (permalink)  
Old 07-13-09, 16:05
ARWinner ARWinner is offline
Registered User
 
Join Date: Jan 2003
Posts: 3,575
Try something like this:

Code:
with t1 (time,name) as 
(select max(time),name from mytable group by name)
select t.* from mytable as t 
inner join t1 on (t.time = t1.time and t.name = t1.name)
Andy
Reply With Quote
  #4 (permalink)  
Old 07-13-09, 23:02
tonkuma tonkuma is offline
Registered User
 
Join Date: Feb 2008
Location: Japan
Posts: 2,193
With OLAP function, it will be not neccesary to scan table(or index) twice.
Code:
SELECT Time, Name, Location
  FROM (SELECT t.*
             , ROW_NUMBER()
                 OVER(PARTITION BY Name
                      ORDER BY Time DESC) rn
          FROM sample_data t
       ) t
 WHERE rn = 1
;
Reply With Quote
  #5 (permalink)  
Old 07-18-09, 21:58
DB2Plus DB2Plus is offline
Registered User
 
Join Date: Jul 2009
Posts: 150
What will happen if we have two or more enties with the same max time for same location:
15:09:10 Tom AUS
15:09:10 Jerry AUS ?

I suppose to get the max name for remove the duplicates:

select distinct mn.*
from
tbl_users nm
join table
(select max(n2.time) as mtime, max(n2.name) mname
from tbl_users n2
where n2.location = nm.location) tt
On
tt.mtime = nm.time
and
tt.mname = nm.name;

Kara Sw.
Reply With Quote
  #6 (permalink)  
Old 07-19-09, 08:36
tonkuma tonkuma is offline
Registered User
 
Join Date: Feb 2008
Location: Japan
Posts: 2,193
Kara, you are wrong.

where n2.location = nm.location
should be
where n2.name = nm.name

and distinct is not neccesary.

using OP's data:
Code:
VALUES
 ('02:03:02', 'Alan',  'AFRICA')
,('04:03:02', 'Alan',  'ASIA'  )
,('05:03:02', 'Alan',  'NA'    )
,('07:27:48', 'Alan',  'ASIA'  )
,('01:09:10', 'Tom',   'EUROPE')
,('02:09:10', 'Tom',   'ASIA'  )
,('05:09:10', 'Tom',   'AUS'   )
,('12:09:10', 'Tom',   'AFRICA')
,('15:09:10', 'Tom',   'AUS'   )
,('05:06:58', 'Nancy', 'AFRICA')
,('08:06:58', 'Nancy', 'ASIA'  )
,('12:06:58', 'Nancy', 'NA'    )
,('15:06:58', 'Nancy', 'AFRICA')
,('17:33:06', 'Mike',  'EUROPE')
)
select nm.*
  from tbl_users nm
  join table
       (select max(n2.time) mtime
             , max(n2.name) mname
          from tbl_users n2
         where n2.location = nm.location) tt
   On  tt.mtime = nm.time
   and tt.mname = nm.name
;
------------------------------------------------------------------------------

TIME     NAME  LOCATION
-------- ----- --------
15:09:10 Tom   AUS     
12:06:58 Nancy NA      

  2 record(s) selected.
Code:
------------------------------ Commands Entered ------------------------------
WITH 
 tbl_users(Time, Name, Location) AS (
VALUES
 ('02:03:02', 'Alan',  'AFRICA')
,('04:03:02', 'Alan',  'ASIA'  )
,('05:03:02', 'Alan',  'NA'    )
,('07:27:48', 'Alan',  'ASIA'  )
,('01:09:10', 'Tom',   'EUROPE')
,('02:09:10', 'Tom',   'ASIA'  )
,('05:09:10', 'Tom',   'AUS'   )
,('12:09:10', 'Tom',   'AFRICA')
,('15:09:10', 'Tom',   'AUS'   )
,('05:06:58', 'Nancy', 'AFRICA')
,('08:06:58', 'Nancy', 'ASIA'  )
,('12:06:58', 'Nancy', 'NA'    )
,('15:06:58', 'Nancy', 'AFRICA')
,('17:33:06', 'Mike',  'EUROPE')
)
select nm.*
  from tbl_users nm
  join table
       (select max(n2.time) mtime
             , max(n2.name) mname
          from tbl_users n2
         where n2.name = nm.name) tt
   On  tt.mtime = nm.time
   and tt.mname = nm.name
;
------------------------------------------------------------------------------

TIME     NAME  LOCATION
-------- ----- --------
07:27:48 Alan  ASIA    
15:09:10 Tom   AUS     
15:06:58 Nancy AFRICA  
17:33:06 Mike  EUROPE  

  4 record(s) selected.
Reply With Quote
  #7 (permalink)  
Old 07-19-09, 09:01
DB2Plus DB2Plus is offline
Registered User
 
Join Date: Jul 2009
Posts: 150
I beleive we are looking for maximum by location, not by name...

But anyway I gave you the right idea how to do this.

With the little change you have the working query.

Kara Sw., NY
Reply With Quote
  #8 (permalink)  
Old 07-19-09, 09:14
DB2Plus DB2Plus is offline
Registered User
 
Join Date: Jul 2009
Posts: 150
If you want to have the righ query, it has to be following:

Quote:
select nm.*
from
tbl_users nm
join table
(select max(n2.time) as mtime, nm.name as mname
from tbl_users n2
where n2.name = nm.name
) tt
On
tt.mtime = nm.time
and
tt.mname = nm.name
;
By, Kara Sw, NY

Last edited by DB2Plus; 07-19-09 at 10:54.
Reply With Quote
  #9 (permalink)  
Old 07-19-09, 10:27
tonkuma tonkuma is offline
Registered User
 
Join Date: Feb 2008
Location: Japan
Posts: 2,193
I thought that it might be better for me to ignore you,
because you didn't understand OP's requirement and you didn't know well at SQL.

Or, do you want to discuss another problem?

OP's requirement is:
Quote:
I want the following as output from a select statement
Time Name Location
---------- ------ --------
07:27:48 Alan ASIA
15:09:10 Tom AUS
15:06:58 Nancy AFRICA
17:33:06 Mike EUROPE
and I showed the result of your query was different from OP's requirement.

Your SQL has syntax error.
1) You can't refer mname(which was named in SELECT clause) in WHERE clause.
2) "mn" in "mn.*" was not defined anyware.
Quote:
select mn.*
from
tbl_users nm
join table
(select max(n2.time) as mtime, nm.name as mname
from tbl_users n2
where n2.mname = nm.name
) tt
On
tt.mtime = nm.time
and
tt.mname = nm.name
;
Reply With Quote
  #10 (permalink)  
Old 07-19-09, 10:50
DB2Plus DB2Plus is offline
Registered User
 
Join Date: Jul 2009
Posts: 150
Thinking before posting !
Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On