Solved

How to a efficiently attatch an extra field with a MAX-aggregated field?

Posted on 2008-10-30
7
281 Views
Last Modified: 2013-12-19
I have two tables ASSOC and JNL.
*********************************************************************************
ASSOC: assosciates the master equipments and slave equipments
*********************************************************************************
MASTER_ID (joint primary key),  SLAVE_ID (joint primary key)
--------------------------------------------------------------------------
1                                                    45
1                                                    46
2                                                    47
2                                                    48


******************************************************
JNL: log the usage of the master equipments
******************************************************
MASTER_ID (foreign key)      TIME_STAMP      USAGE     LOG_ID (primary key)
-----------------------------------------------------------------------------------------------
1                                              2008/10/01          100             5
1                                              2008/09/01            20             2
1                                              2008/05/01          100             1
2                                              2008/09/30            50             4
2                                              2008/09/10            80             3


I want to make a SQL query to return this table:
MASTER_ID, SLAVE_ID,  TIME_STAMP      USAGE
-----------------------------------------------------------------------------
1                             45         2008/10/01          100
1                             46         2008/10/01          100
2                             47         2008/09/30            50            
2                             48         2008/09/30            50            


The returned table should have the most recent usage date of master equipment for each association, together with the usage amount of that time.

I only find the following SQL statement getting the most recent time stamp, but don't know how to let the USAGE go with it.
*****************************************************************************************
SELECT ASSOC.MASTER_ID, ASSOC.SLAVE_ID, MAX(TIME_STAMP)
FROM ASSOC, JNL
WHERE ASSOC.MASTER_ID = JNL.MASTER_ID
GROUP BY ASSOC.MASTER_ID, ASSOC.SLAVE_ID
*****************************************************************************************

Do yo have any idea to get the USAGE together?

Thank you!
0
Comment
Question by:huangs3
7 Comments
 
LVL 5

Expert Comment

by:Cvijo123
ID: 22846434
if your log_ID is primary key auto identity why not use last ID inserted for your master_id as last usage ?
if that is case then you should use something like:
SELECT

	ASSOC.MASTER_ID,

	ASSOC.SLAVE_ID,

	JNL.USAGE, 

	JNL.TIME_STAMP

FROM ASSOC

	left join ( Select max(LOG_ID) as LOG_ID, MASTER_ID from JNL group by MASTER_ID ) lastEntry

		on ASSOC.Master_ID = lastEntry.Master_ID

	left join JNL

		on JNL.Log_ID = lastEntry.Log_id

Open in new window

0
 
LVL 27

Accepted Solution

by:
sujith80 earned 400 total points
ID: 22847147
Use this query.
select X.master_id, X.slave_id, Y.time_stamp, Y.usage

from 

ASSOC X, 

( 

select master_id, time_stamp, usage

from (

select master_id, time_stamp, usage, row_number() over(partition by master_id order by time_stamp desc) rn

from JNL)

where rn = 1

) Y

where X.master_id = Y.master_id;

Open in new window

0
 
LVL 9

Expert Comment

by:MarkusId
ID: 22848349

SELECT ASSOC.MASTER_ID, ASSOC.SLAVE_ID, max(TIME_STAMP), max(usage)

FROM test1 ASSOC, test2 JNL

WHERE ASSOC.MASTER_ID = JNL.MASTER_ID

  AND time_stamp = (SELECT max(i.time_stamp)

                       FROM test2 i

                      WHERE i.master_id = jnl.master_id)

GROUP BY ASSOC.MASTER_ID, ASSOC.SLAVE_ID

/

Open in new window

0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 27

Expert Comment

by:sujith80
ID: 22848609
MarkusId:
Your approach uses a correlated subquery. It will be slower as there are multiple FULL table scans of JNL.
0
 
LVL 9

Expert Comment

by:MarkusId
ID: 22848859
I wasn't aware of that, isn't the sub-query to be evaluated as the last condition? And as there is a foreign key on master_id of JNL these shouldn't be full table scans.

However, I've experienced often enough that there are differences between the expected and the real behaviour of a database, so you might be right.


SELECT ASSOC.MASTER_ID, ASSOC.SLAVE_ID, max(i.MAX_TIME_STAMP), max(jnl.usage)

FROM (SELECT max(time_stamp) max_time_stamp, master_id

        FROM JNL

       GROUP BY master_id) i, ASSOC, JNL

WHERE ASSOC.MASTER_ID = JNL.MASTER_ID

  AND jnl.time_stamp = i.max_time_stamp

  AND jnl.master_id = i.master_id

GROUP BY ASSOC.MASTER_ID, ASSOC.SLAVE_ID

/

Open in new window

0
 
LVL 10

Assisted Solution

by:dbmullen
dbmullen earned 100 total points
ID: 22850179
same as sujith80 but with less lines.
if you really want to see what it does.
run this as a test
SELECT x.master_id, x.slave_id, y.time_stamp, y.USAGE,
        ROW_NUMBER () OVER (PARTITION BY y.master_id
                            ORDER BY y.time_stamp DESC) rn
          FROM jnl y, assoc x
         WHERE x.master_id = y.master_id

SELECT master_id, slave_id, time_stamp, USAGE

  FROM (SELECT x.master_id, x.slave_id, y.time_stamp, y.USAGE,

        ROW_NUMBER () OVER (PARTITION BY y.master_id 

                            ORDER BY y.time_stamp DESC) rn

          FROM jnl y, assoc x

         WHERE x.master_id = y.master_id)

 WHERE rn = 1

;

Open in new window

0
 

Author Comment

by:huangs3
ID: 22851041
Cvijo123:
    That's a good idea in practice, but strictly speaking we cannot garantee that primary key field follows the order of time.
Sui
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

I remember the day when someone asked me to create a user for an application developement. The user should be able to create views and materialized views and, so, I used the following syntax: (CODE) This way, I guessed, I would ensure that use…
PL/SQL can be a very powerful tool for working directly with database tables. Being able to loop will allow you to perform more complex operations, but can be a little tricky to write correctly. This article will provide examples of basic loops alon…
Via a live example show how to connect to RMAN, make basic configuration settings changes and then take a backup of a demo database
This video shows how to Export data from an Oracle database using the Original Export Utility.  The corresponding Import utility, which works the same way is referenced, but not demonstrated.

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now