Connecting Tech Pros Worldwide Forums | Help | Site Map

Improving a SQL statement

Newbie
 
Join Date: Jan 2008
Posts: 13
#1: Sep 14 '09
Is there any way to improve this statement? A is the header table while B has 0 to many records for each record in A. I'm trying to pick only the latest record in B for the associated seq in A.

Expand|Select|Wrap|Line Numbers
  1. select * from A left outer join B on B.seq = A.seq
  2. and B.order = (select max(order) from B where B.seq = A.seq)

Newbie
 
Join Date: Oct 2009
Posts: 5
#2: 4 Weeks Ago

re: Improving a SQL statement


Hi,

I'm a bit surprised that this query is working in its current form. When I tried to run it i got the following:
-----------------------------------------------------------------------------------------------
SQL0338N An ON clause associated with a JOIN operator or in a MERGE statement is not valid.

Explanation:

An ON clause associated with a JOIN operator or in a MERGE
statement is not valid for one of the following reasons.

o The ON clause cannot include any subqueries.
o Column references in an ON clause must only reference columns
of tables that are in the scope of the ON clause.
o Scalar fullselects are not allowed in the expressions of an
ON clause.
o A function referenced in an ON clause of a full outer join
must be deterministic and have no external action.
o A dereference operation (->) cannot be used.
o A SQL function or SQL method cannot be used.
o The ON clause cannot include an XMLQUERY or XMLEXISTS
expression.
---------------------------------------------------------------------------------------

1. Are you sure this is a DB2 query? if not then this might be in the wrong place.

2. Assuming your tables are like that below.

Expand|Select|Wrap|Line Numbers
  1. A                                        B                         
  2. Seq         Order                      Seq    order
  3. 1               1                      1         1
  4. 2               2                      1         2 
  5.                                        1         3
  6.                                        1         4
  7.                                        2         1 
  8.                                        2         2
  9.                                        2         3
  10.                                        2         4 
  11.  
  12. And the desired output is
  13.  
  14. Seq         Order
  15. 1                4
  16. 2                4
  17.  
  18. try..
  19. -------------------------------------------
  20. select  r2.seq, r2.ord from 
  21. (
  22.       select r1.seq, r1.ord  from
  23.       (
  24.     select distinct b.seq, max(b.ord)  from b   
  25.                    group by b.seq
  26.        ) r1
  27. left outer join a on r1."ord" = a."ord" 
  28. )r2;
  29. -------------------------------------------
The advantage here is that you are not doing subselects for each row satisfying the join condition. Subselects are expensive their use should be minimized where possible.
Newbie
 
Join Date: Jan 2008
Posts: 13
#3: 4 Weeks Ago

re: Improving a SQL statement


I tried something similar, but it runs slower than the original. I'm guessing its because these temporary tables don't use indexes. The query has to return the rows back from both tables, and TABLEA has to be on the left of the outer join which was why I couldn't just use what you wrote above.
Expand|Select|Wrap|Line Numbers
  1. select *
  2. from TABLEA
  3. left outer join (select * from TABLEB r2                  
  4.               left outer join (select ceseq mseq, max(ceeord) mord 
  5.               from TABLEB group by ceseq) r1              
  6.               on r2.ceseq = r1.mseq and r2.ceeord = mord           
  7.                             ) r3 on cmseq = ceseq and ceeord = mord
Newbie
 
Join Date: Oct 2009
Posts: 5
#4: 3 Weeks Ago

re: Improving a SQL statement


Are you using the DB2 Control Center to run this query? If so can you do a visual explain and attach that to the thread, that should show which indexes are used by the db2 optimizer as well as costs of doing joins, sorts etc to help find ways to optimize this query.

If you do not have access to the DB2 Control Center you can use the command line dynexpln or db2exfmt tools to gather the same information.
Newbie
 
Join Date: Jan 2008
Posts: 13
#5: 3 Weeks Ago

re: Improving a SQL statement


There is no control center and those commands don't work on the iSeries and as/400.
Newbie
 
Join Date: Oct 2009
Posts: 5
#6: 3 Weeks Ago

re: Improving a SQL statement


Info on gathering explain data for AS/400:

http://www.redbooks.ibm.com/redpapers/pdfs/redp0502.pdf
Member
 
Join Date: Aug 2007
Posts: 51
#7: 2 Weeks Ago

re: Improving a SQL statement


In general, I have found that the OLAP functions perform well in this regard. You might want to try something like the following sample code:

Expand|Select|Wrap|Line Numbers
  1. create table A(seq int, id char(1));
  2. insert into A values (1,'A');
  3. insert into A values (2,'B');
  4. insert into A values (3,'C');
  5.  
  6. create table B(seq int, order int);
  7. insert into B values (1,1);
  8. insert into B values (1,2);
  9. insert into B values (1,3);
  10. insert into B values (1,4);
  11. insert into B values (2,2);
  12. insert into B values (2,3);
  13. insert into B values (2,4);
  14. insert into B values (2,5);
  15.  
  16. select distinct A.seq, A.id, max(B.order) over(partition by B.seq) as max_order
  17.   from A
  18.   left outer join
  19.        B
  20.     on A.seq = B.seq;
Reply