473,748 Members | 2,621 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

DB2 subselect problem

I have the following statement which I run successfully in... 1 hour 10
minutes.

SELECT
a.tsgicd as ACCT_ID,
a.tsa5cd as SEC_ID,
CASE
WHEN (SUBSTRING(a.ts gicd, 6, 1) = 'R'
or SUBSTRING(a.tsg icd, 6, 1) = 'Y'
or SUBSTRING(a.tsg icd, 6, 1) = '0'
or SUBSTRING(a.tsg icd, 6, 1) = '1'
or SUBSTRING(a.tsg icd, 6, 1) = '2'
or SUBSTRING(a.tsg icd, 6, 1) = '3'
or SUBSTRING(a.tsg icd, 6, 1) = '4'
or SUBSTRING(a.tsg icd, 6, 1) = '5'
or SUBSTRING(a.tsg icd, 6, 1) = '6'
or SUBSTRING(a.tsg icd, 6, 1) = '7'
or SUBSTRING(a.tsg icd, 6, 1) = '8'
or SUBSTRING(a.tsg icd, 6, 1) = '9'
) THEN (select max(main.bvmnt) from
vmdprdta.gnbvfm 00 main where main.bv#cpte =A.TSGICD and
main.bvsecid=A. TSA5CD and main.bvdteeff = (select max(bv.bvdteeff )
from vmdprdta.gnbvfm 00 bv where bv.bv#cpte = A.TSGICD and
bv.BVSECID=A.TS A5CD ))
ELSE NULL
END as BV_MNT,
a.tsalpc as LOAN_RATE,
a.tsbpva as LOAN_VALUE,
a.tsbqva as MKT_VALUE
FROM
table1 a
left outer join table2 d on a.tsannb = d.itannb
left outer join table3 G on a.tsannb = G.IXANNB,
table4 b,
table5 c,
table6 e,
table7 f
WHERE
a.tsgicd >= '01 '
and (a.tsgicd <= '7999999' or
a.tsgicd = '8860686' or
a.tsgicd = '8860694' or
a.tsgicd = '8860306' or
a.tsgicd = '8860314' or
a.tsgicd = '8860520' or
a.tsgicd = '8860538' or
a.tsgicd = '8860801' or
a.tsgicd = '8860819')
and a.tsgicd = b.acgicd
and b.acbodc = 0
and b.acd2st <> 'D'
and b.acbwcd = c.orrept
and c.ordivi = 'ESCPT'
and a.tsannb = e.tiannb
and e.ticaid = f.caid

I know that the problem comes from the utilisation of the Max function.
Instead of using the max function, I wanted the subselect to do
something like this:

(select first(main.bvmn t) from vmdprdta.gnbvfm 00 main where
main.bv#cpte =A.TSGICD and main.bvsecid=A. TSA5CD order by main.bvdteeff
desc )

OR

(select (main.bvmnt) from vmdprdta.gnbvfm 00 main where main.bv#cpte
=A.TSGICD and main.bvsecid=A. TSA5CD order by main.bvdteeff desc fetch
first row only)

OR

(select (main.bvmnt) from vmdprdta.gnbvfm 00 main where main.bv#cpte
=A.TSGICD and main.bvsecid=A. TSA5CD order by main.bvdteeff desc limit
1)

Unfortunately, the Order by clause is not permitted in a subselect,
First doesn't exist in DB2 and Fetch first x-rows is not allowed in a
subselect...

Does anyone have a solution?

Thanks in advance.

Dec 23 '05 #1
6 5016
Not an answer to the main question.

Is there a reason you are not using IN()?

B.

Dec 23 '05 #2
If you meant to use IN instead of bvdteeff =, there is no particular
reason, except the fact that it explicitly tells that there is only one
possible result, but since I use a max() in the sub-sub query, I will
always get only one result. Also, using IN should be slower.

Dec 23 '05 #3

"Sebastien" <ro***********@ gmail.com> wrote in message
news:11******** *************@f 14g2000cwb.goog legroups.com...
I have the following statement which I run successfully in... 1 hour 10
minutes.

SELECT
a.tsgicd as ACCT_ID,
a.tsa5cd as SEC_ID,
CASE
WHEN (SUBSTRING(a.ts gicd, 6, 1) = 'R'
or SUBSTRING(a.tsg icd, 6, 1) = 'Y'
or SUBSTRING(a.tsg icd, 6, 1) = '0'
or SUBSTRING(a.tsg icd, 6, 1) = '1'
or SUBSTRING(a.tsg icd, 6, 1) = '2'
or SUBSTRING(a.tsg icd, 6, 1) = '3'
or SUBSTRING(a.tsg icd, 6, 1) = '4'
or SUBSTRING(a.tsg icd, 6, 1) = '5'
or SUBSTRING(a.tsg icd, 6, 1) = '6'
or SUBSTRING(a.tsg icd, 6, 1) = '7'
or SUBSTRING(a.tsg icd, 6, 1) = '8'
or SUBSTRING(a.tsg icd, 6, 1) = '9'
) THEN (select max(main.bvmnt) from
vmdprdta.gnbvfm 00 main where main.bv#cpte =A.TSGICD and
main.bvsecid=A. TSA5CD and main.bvdteeff = (select max(bv.bvdteeff )
from vmdprdta.gnbvfm 00 bv where bv.bv#cpte = A.TSGICD and
bv.BVSECID=A.TS A5CD ))
ELSE NULL
END as BV_MNT,
a.tsalpc as LOAN_RATE,
a.tsbpva as LOAN_VALUE,
a.tsbqva as MKT_VALUE
FROM
table1 a
left outer join table2 d on a.tsannb = d.itannb
left outer join table3 G on a.tsannb = G.IXANNB,
table4 b,
table5 c,
table6 e,
table7 f
WHERE
a.tsgicd >= '01 '
and (a.tsgicd <= '7999999' or
a.tsgicd = '8860686' or
a.tsgicd = '8860694' or
a.tsgicd = '8860306' or
a.tsgicd = '8860314' or
a.tsgicd = '8860520' or
a.tsgicd = '8860538' or
a.tsgicd = '8860801' or
a.tsgicd = '8860819')
and a.tsgicd = b.acgicd
and b.acbodc = 0
and b.acd2st <> 'D'
and b.acbwcd = c.orrept
and c.ordivi = 'ESCPT'
and a.tsannb = e.tiannb
and e.ticaid = f.caid

I know that the problem comes from the utilisation of the Max function.
Instead of using the max function, I wanted the subselect to do
something like this:

(select first(main.bvmn t) from vmdprdta.gnbvfm 00 main where
main.bv#cpte =A.TSGICD and main.bvsecid=A. TSA5CD order by main.bvdteeff
desc )

OR

(select (main.bvmnt) from vmdprdta.gnbvfm 00 main where main.bv#cpte
=A.TSGICD and main.bvsecid=A. TSA5CD order by main.bvdteeff desc fetch
first row only)

OR

(select (main.bvmnt) from vmdprdta.gnbvfm 00 main where main.bv#cpte
=A.TSGICD and main.bvsecid=A. TSA5CD order by main.bvdteeff desc limit
1)

Unfortunately, the Order by clause is not permitted in a subselect,
First doesn't exist in DB2 and Fetch first x-rows is not allowed in a
subselect...

Does anyone have a solution?

Thanks in advance.

What makes you think that max() is the problem? Have you used Explain to
prove this? If not, I think you should do an Explain to see what it says.

I don't see any inherent reason why max() should be slow. In fact, I think
the opposite is more likely to be true: if the column in which you are
trying to get a max() value has an index on it, DB2 could very well get you
that max() value via a single access to the root page of the index which
should be very fast.

Also, I don't think that in() is inherently any slower than using several
equals conditions that have been "OR"ed together. Due to DB2 query rewrite
capabilities, I think the two approaches would have the same performance.
Also, the IN version would be shorter and easier to read, which makes it
easier to maintain.

One other small thing: it's a bad idea to make literals in conditions longer
than they need to be. This predicate:

a.tsgicd >= '01 '

can actually hurt your performance significantly if the literal is longer
than the column to which you are comparing it. For example, if the tsgicd
column is only 3 characters long and the search condition is longer than
that, you guarantee that no index can be used on that column to find
qualifying rows. Make sure that the search value, '01 ' in this case, is
no wider than the tsgicd column itself. That alone might help your query
significantly - or not, since I see that your other predicates involving the
tsgicd column are also long. But it is still wise to be sure that '01 '
is no longer than the column; if you typed just one extra blank, which is
easy to do, you'd find that the query could suffer.

My advice to you is to try using whatever flavour of Explain you like best
to look at the query and see where the bottlenecks are. Also, try some
variations like using in() instead of multiple equal predicates linked with
OR and see if it makes any difference at all.

Personally, I like Visual Explain which clearly shows which the cost of each
part of the query and gives clues as to why that part is expensive. But you
didn't state which variety of DB2 you are using or what platform you are on
so I'm not sure if you have Visual Explain.

Rhino
Dec 23 '05 #4
Sebastien wrote:
I have the following statement which I run successfully in... 1 hour 10
minutes.

SELECT
a.tsgicd as ACCT_ID,
a.tsa5cd as SEC_ID,
CASE
WHEN (SUBSTRING(a.ts gicd, 6, 1) = 'R'
or SUBSTRING(a.tsg icd, 6, 1) = 'Y'
or SUBSTRING(a.tsg icd, 6, 1) = '0'
or SUBSTRING(a.tsg icd, 6, 1) = '1'
or SUBSTRING(a.tsg icd, 6, 1) = '2'
or SUBSTRING(a.tsg icd, 6, 1) = '3'
or SUBSTRING(a.tsg icd, 6, 1) = '4'
or SUBSTRING(a.tsg icd, 6, 1) = '5'
or SUBSTRING(a.tsg icd, 6, 1) = '6'
or SUBSTRING(a.tsg icd, 6, 1) = '7'
or SUBSTRING(a.tsg icd, 6, 1) = '8'
or SUBSTRING(a.tsg icd, 6, 1) = '9'
) THEN (select max(main.bvmnt) from
vmdprdta.gnbvfm 00 main where main.bv#cpte =A.TSGICD and
main.bvsecid=A. TSA5CD and main.bvdteeff = (select max(bv.bvdteeff )
from vmdprdta.gnbvfm 00 bv where bv.bv#cpte = A.TSGICD and
bv.BVSECID=A.TS A5CD ))
ELSE NULL
END as BV_MNT,
a.tsalpc as LOAN_RATE,
a.tsbpva as LOAN_VALUE,
a.tsbqva as MKT_VALUE
FROM
table1 a
left outer join table2 d on a.tsannb = d.itannb
left outer join table3 G on a.tsannb = G.IXANNB,
table4 b,
table5 c,
table6 e,
table7 f
WHERE
a.tsgicd >= '01 '
and (a.tsgicd <= '7999999' or
a.tsgicd = '8860686' or
a.tsgicd = '8860694' or
a.tsgicd = '8860306' or
a.tsgicd = '8860314' or
a.tsgicd = '8860520' or
a.tsgicd = '8860538' or
a.tsgicd = '8860801' or
a.tsgicd = '8860819')
and a.tsgicd = b.acgicd
and b.acbodc = 0
and b.acd2st <> 'D'
and b.acbwcd = c.orrept
and c.ordivi = 'ESCPT'
and a.tsannb = e.tiannb
and e.ticaid = f.caid

I know that the problem comes from the utilisation of the Max function.
Instead of using the max function, I wanted the subselect to do
something like this:

(select first(main.bvmn t) from vmdprdta.gnbvfm 00 main where
main.bv#cpte =A.TSGICD and main.bvsecid=A. TSA5CD order by main.bvdteeff
desc )

OR

(select (main.bvmnt) from vmdprdta.gnbvfm 00 main where main.bv#cpte
=A.TSGICD and main.bvsecid=A. TSA5CD order by main.bvdteeff desc fetch
first row only)

OR

(select (main.bvmnt) from vmdprdta.gnbvfm 00 main where main.bv#cpte
=A.TSGICD and main.bvsecid=A. TSA5CD order by main.bvdteeff desc limit
1)

Unfortunately, the Order by clause is not permitted in a subselect,
First doesn't exist in DB2 and Fetch first x-rows is not allowed in a
subselect...

Does anyone have a solution?

Thanks in advance.

Which version/platform of DB2?
DB2 V8 for LUW supports both ORDER By and FETCH FIRST is subqueries
strating with FP2 I believe.

Cheers
Serge
--
Serge Rielau
DB2 Solutions Development
DB2 UDB for Linux, Unix, Windows
IBM Toronto Lab
Dec 24 '05 #5
OR predicates can be rewritten to an IN predicate by DB2, if they are
in where clause but not in CASE statement. IN predicate is supposed to
be more efficient than multiple ORs in that it calculates substr only
once.

Also check the explain if inner join predicates and local predicates on
table a, b and c are pushed down below outer join. If not, you may move
all or some WHERE predicates to the FROM clause, because they would
prune off many rows prior to the outjoin computation.

Dec 25 '05 #6
I doubt that the MAX() is the problem. What seems more likely to me
(not having a database to check the plan on this query) is that the
problem would be the nested - nested correlated subqueries that you
have setup. I would suggest making sure the table vmdprdta.gnbvfm 00 is
indexed ideally for the subqueries on the two columns you are querying
on. Or, maybe even better, rewrite the query to not use any correlated
subqueries at all. Here is an example that should work (it also
incorporates the suggestions of using the IN clause, too):

with not_subselect(b vmnt, row_num) as (select bvmnt,
row_number() over(partition by bv#cpte, bvsecid order by bvdteef
desc) as row_num),
not_sub_2(bvmnt ) as (select bvmnt from not_subselect where row_num
= 1)
SELECT
a.tsgicd as ACCT_ID,
a.tsa5cd as SEC_ID,
CASE WHEN SUBSTRING(a.tsg icd, 6, 1) in ('R' , 'Y', '0', '1', '2', '3',

'4', '5', '6', '7', '8', '9')
THEN ns2.bvmnt
ELSE NULL END as bv_mnt,
a.tsalpc as LOAN_RATE,
a.tsbpva as LOAN_VALUE,
a.tsbqva as MKT_VALUE
FROM
table1 a
left outer join table2 d on a.tsannb = d.itannb
left outer join table3 G on a.tsannb =
G.IXANNB,
table4 b,
table5 c,
table6 e,
table7 f,
left outer join not_sub_2 ns2 on ns2.bv#cpte = A.TSGICD and
ns2.bvsecid = A.TSA5CD
WHERE
(a.tsgicd between '01 ' and '7999999'
or a.tsgicd in ('8860686', '8860694', '8860306', '8860314',
'8860520',
'8860538', '8860801', '8860819'))
and a.tsgicd = b.acgicd
and b.acbodc = 0
and b.acd2st <> 'D'
and b.acbwcd = c.orrept
and c.ordivi = 'ESCPT'
and a.tsannb = e.tiannb
and e.ticaid = f.caid

Chris

Dec 29 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
1748
by: limbert | last post by:
------=_NextPart_000_0001_01C34D7B.DFBF53C0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Hi, =20 I was reading the manual and it said that the subselect is only
6
16330
by: Greg Stark | last post by:
So I have a query in which some of the select values are subqueries. The subqueries are aggregates so I don't want to turn this into a join, it would become too complex and postgres would have trouble optimizing things. So my question is, is there some way to have a subselect return multiple columns and break those out in the outer query? Something like: SELECT x,y,z,
3
7202
by: Neil Zanella | last post by:
Hello, I would like to ask the about the following... PostgreSQL allows tables resulting from subselects to be renamed with an optional AS keyword whereas Oracle 9 will report an error whenever a table is renamed with the AS keyword. Furthermore, in PostgreSQL when the result of a subselect is referenced in an outer select it is required that the subselect result be named, whereas this is not true in Oracle. I wonder what standard SQL...
4
2750
by: James | last post by:
I have a performance problem with the following query and variations on the subselect. The EXISTS version of the first example will complete in ~10 minutes. The NOT logic in both the examples makes them both keep running long enough that a communications error is the only result returned so far. This is a federated view computer ~160 k rows, computer_sys_id is PK . matched_sware ~ 18 million no PK , no index. Any suggestions on...
4
7563
by: dtwalter | last post by:
Is it possible to ORDER BY a SubSelect? I don't see why it wouldn't be, but I'm having some trouble. Hopefully it's just a simple error in syntax and somebody can tell me. Here's what I'm trying to do... I've got two tables: Table1: TestData Filename Bird FileB Blue FileA Circle FileC
1
1725
by: Marco Lazzeri | last post by:
I'd like to reference values returned by a subselect in the same SELECT query. Example: SELECT id, ( SELECT COUNT(*) FROM second ) AS value_to_reference, ( value_to_reference + 1 ) AS value_that_uses_referenced_one FROM first;
4
5485
by: Chris Kratz | last post by:
Hello all, We have run into what appears to be a problem with rules and subselects in postgres 7.4.1. We have boiled it down to the following test case. If anyone has any thoughts as to why this would be happening, we would appreciate feedback. We have tested on 7.3.4, 7.3.6 and 7.4.1 and all exhibit the same behavior. Test case one tries to populate table2 from table1 with records that are not in table2 already. Table2 gets...
6
3223
by: Alex P | last post by:
Hi, when creating a query with a subselect SELECT name, (SELECT max(pop) FROM cities WHERE cities.state = states.name) AS max_pop FROM states; then it is not possible to sort after max_pop or use max_pop in a function or a CASE. am I dont anything wrong or is this meant to be the case?
5
3769
by: Bart op de grote markt | last post by:
Hello, I have a problem with a subselect I use in a stored procedure: UPDATE #TEMP_TABLE SET P_ID_1=(SELECT top 1 b.P_ID_1 from #TEMP_TABLE b where b.ID=PARENT_ID), P_ID_2=PARENT_ID, P_ID_3=ID WHERE PARENT_ID IN (SELECT P_ID_2
0
8832
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9562
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
9333
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9254
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8255
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6799
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6078
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
1
3319
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
2217
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.