473,773 Members | 2,334 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

How do I avoid this corelated subquery?

Hello,
I have a situation which would essentially use a co-related subquery.
I am trying to avoid using a co-related subquery due to its slow
performanc and use a join statement instead.

Here is what I am trying to do:

Tables:
========
Limit
-------
RelID ProdID Days Amt1 Amt2
----- ------ ---- ---- ------
148 2 30 15000 30000
148 2 7 1000 2500

Temp Limits
-----------
RelID ProdID MaxDays Amt1 Amt2
----- ------ ----- ------ ------
148 2 1 7500 1000
148 2 7 17500 500
148 2 30 2500 2000
148 2 90 25000 750
148 2 180 7500 -300

I want the totals of Amt1 and Amt2 in the TempLimits table added to
each row in the Limits table where the Days in the Limits Table >=
MaxDays in TempLimits
So, when I run the query with the above data
I need to get

RelID ProdID Days Amt1 Amt2
----- ------ ---- ------ ------
148 2 30 42500 (15000+7500+175 00+2500) 33500
(30000+1000+500 +2000)
148 2 7 26000 (1000+7500+1750 0) 4000
(2500+1000+500)

*************** *************** *************** *************** *************** *
Here is the query that I have right now...

update Limit
set Amt1 = isnull(Amt1,0) + IsNull(temptabl e.temp_Amt1, 0)
, Amt2 = isnull(Amt2,0) + IsNull(temptabl e.temp_Amt2, 0)
from Limit inner join
(
select Templimits.rela tionship_id relationship_id ,
Templimits.prod uct_id product_id, sum(Templimits. Amt1) temp_Amt1,
sum(Templimits. Amt2) temp_Amt2
from TempLimits
WHERE TEMPLIMITS.MAXD AYS <= LIMIT.DAYS
group by limit.relations hip_id, limit.product_i d
) temptable
on Limit.relid = temptable.relid and
Limit.prodid = temptable.prodi d

*************** *************** *************** *************** *************** ***
As you would see here, I am trying to use the condition for Days
(listed in the query in CAPS) inside the inner query which would not
work... Is there any way I can do this apart from using temp tables
and co-related subqueries?

Thanks in advance
Kannan
Jul 20 '05 #1
7 4003
"Kannan" <pv*******@yaho o.com> wrote in message
news:b4******** *************** **@posting.goog le.com...
Hello,
I have a situation which would essentially use a co-related subquery.
I am trying to avoid using a co-related subquery due to its slow
performanc and use a join statement instead.

Here is what I am trying to do:

Tables:
========
Limit
-------
RelID ProdID Days Amt1 Amt2
----- ------ ---- ---- ------
148 2 30 15000 30000
148 2 7 1000 2500

Temp Limits
-----------
RelID ProdID MaxDays Amt1 Amt2
----- ------ ----- ------ ------
148 2 1 7500 1000
148 2 7 17500 500
148 2 30 2500 2000
148 2 90 25000 750
148 2 180 7500 -300

I want the totals of Amt1 and Amt2 in the TempLimits table added to
each row in the Limits table where the Days in the Limits Table >=
MaxDays in TempLimits
So, when I run the query with the above data
I need to get

RelID ProdID Days Amt1 Amt2
----- ------ ---- ------ ------
148 2 30 42500 (15000+7500+175 00+2500) 33500
(30000+1000+500 +2000)
148 2 7 26000 (1000+7500+1750 0) 4000
(2500+1000+500)

*************** *************** *************** *************** *************** *
Here is the query that I have right now...

update Limit
set Amt1 = isnull(Amt1,0) + IsNull(temptabl e.temp_Amt1, 0)
, Amt2 = isnull(Amt2,0) + IsNull(temptabl e.temp_Amt2, 0)
from Limit inner join
(
select Templimits.rela tionship_id relationship_id ,
Templimits.prod uct_id product_id, sum(Templimits. Amt1) temp_Amt1,
sum(Templimits. Amt2) temp_Amt2
from TempLimits
WHERE TEMPLIMITS.MAXD AYS <= LIMIT.DAYS
group by limit.relations hip_id, limit.product_i d
) temptable
on Limit.relid = temptable.relid and
Limit.prodid = temptable.prodi d

*************** *************** *************** *************** *************** ***
As you would see here, I am trying to use the condition for Days
(listed in the query in CAPS) inside the inner query which would not
work... Is there any way I can do this apart from using temp tables
and co-related subqueries?

Thanks in advance
Kannan


CREATE TABLE Limits
(
relid INT NOT NULL,
prodid INT NOT NULL,
days INT NOT NULL,
amt1 INT NOT NULL,
amt2 INT NOT NULL,
PRIMARY KEY (relid, prodid, days)
)

CREATE TABLE TempLimits
(
relid INT NOT NULL,
prodid INT NOT NULL,
maxdays INT NOT NULL,
amt1 INT NOT NULL,
amt2 INT NOT NULL,
PRIMARY KEY (relid, prodid, maxdays)
)

UPDATE Limits
SET amt1 = amt1 + (SELECT SUM(amt1)
FROM TempLimits AS TL
WHERE TL.relid = relid AND
TL.prodid = prodid AND
TL.maxdays <= days),
amt2 = amt2 + (SELECT SUM(amt2)
FROM TempLimits AS TL
WHERE TL.relid = relid AND
TL.prodid = prodid AND
TL.maxdays <= days)
WHERE EXISTS (SELECT *
FROM TempLimits AS TL
WHERE TL.relid = relid AND
TL.prodid = prodid AND
TL.maxdays <= days)

--
JAG
Jul 20 '05 #2
Kannan (pv*******@yaho o.com) writes:
*************** *************** *************** *************** *************** *
Here is the query that I have right now...

update Limit
set Amt1 = isnull(Amt1,0) + IsNull(temptabl e.temp_Amt1, 0)
, Amt2 = isnull(Amt2,0) + IsNull(temptabl e.temp_Amt2, 0)
from Limit inner join
(
select Templimits.rela tionship_id relationship_id ,
Templimits.prod uct_id product_id, sum(Templimits. Amt1) temp_Amt1,
sum(Templimits. Amt2) temp_Amt2
from TempLimits
WHERE TEMPLIMITS.MAXD AYS <= LIMIT.DAYS
group by limit.relations hip_id, limit.product_i d
) temptable
on Limit.relid = temptable.relid and
Limit.prodid = temptable.prodi d
************** *************** *************** *************** *************** *


I can't see that that query can even compile. You are referring to
limit in the derived table, but I was under the belief that a derived
table cannot refer to tables in the outer part of the query. And in any
case, there are no relid and prodid columns in the derived table temptable.

I would suggest that you post:

o CREATE TABLE and CREATE INDEX statements for your tables.
o The actual query you run.
o The output when you run the UPDATE statement with
SET STATISTICS PROFILE ON.

This makes it a lot easier to give a more accurate response, and relieves
us from what guess what your query actually is.

--
Erland Sommarskog, SQL Server MVP, so****@algonet. se

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techinf...2000/books.asp
Jul 20 '05 #3
John Gilson (ja*@acm.org) writes:
UPDATE Limits
SET amt1 = amt1 + (SELECT SUM(amt1)
FROM TempLimits AS TL
WHERE TL.relid = relid AND
TL.prodid = prodid AND
TL.maxdays <= days),
amt2 = amt2 + (SELECT SUM(amt2)
FROM TempLimits AS TL
WHERE TL.relid = relid AND
TL.prodid = prodid AND
TL.maxdays <= days)
WHERE EXISTS (SELECT *
FROM TempLimits AS TL
WHERE TL.relid = relid AND
TL.prodid = prodid AND
TL.maxdays <= days)


John, when you say "TL.relid = relid", does not the prefix-less "relid"
refer to TempLimits?

Also, I am afraid that this is not going to perform overly well, since
SQL Server will resolve the same condition thrice. It is usually better
to have a derived table. If I understand this right it would be:

CREATE TABLE Limits
(
relid INT NOT NULL,
prodid INT NOT NULL,
days INT NOT NULL,
amt1 INT NOT NULL,
amt2 INT NOT NULL,
PRIMARY KEY (relid, prodid, days)
)

CREATE TABLE Templimits
(
relid INT NOT NULL,
prodid INT NOT NULL,
maxdays INT NOT NULL,
amt1 INT NOT NULL,
amt2 INT NOT NULL,
PRIMARY KEY (relid, prodid, maxdays)
)

INSERT Limits VALUES (148, 2, 30, 15000, 30000)
INSERT Limits VALUES (148, 2, 7, 1000, 2500)

INSERT Templimits VALUES (148, 2, 1, 7500, 1000)
INSERT Templimits VALUES (148, 2, 7, 17500, 500)
INSERT Templimits VALUES (148, 2, 30, 2500, 2000)
INSERT Templimits VALUES (148, 2, 90, 25000, 750)
INSERT Templimits VALUES (148, 2, 180, 7500, -300)

UPDATE Limits
SET amt1 = L.amt1 + coalesce(d.amt1 , 0),
amt2 = L.amt2 + coalesce(d.amt2 , 0)
FROM Limits L
JOIN (SELECT TL.relid, TL.prodid, L1.days,
amt1 = SUM(TL.amt1), amt2 = SUM(TL.amt2)
FROM Templimits TL
JOIN Limits L1 ON L1.relid = TL.relid
AND L1.prodid = TL.prodid
AND TL.maxdays <= L1.days
GROUP BY TL.relid, TL.prodid, L1.days) AS d
ON d.relid = L.relid
AND d.prodid = L.prodid
AND d.days = L.days
go
select * from Limits
go
drop table Limits, Templimits
--
Erland Sommarskog, SQL Server MVP, so****@algonet. se

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techinf...2000/books.asp
Jul 20 '05 #4
"Erland Sommarskog" <so****@algonet .se> wrote in message news:Xn******** ************@12 7.0.0.1...
John Gilson (ja*@acm.org) writes:
UPDATE Limits
SET amt1 = amt1 + (SELECT SUM(amt1)
FROM TempLimits AS TL
WHERE TL.relid = relid AND
TL.prodid = prodid AND
TL.maxdays <= days),
amt2 = amt2 + (SELECT SUM(amt2)
FROM TempLimits AS TL
WHERE TL.relid = relid AND
TL.prodid = prodid AND
TL.maxdays <= days)
WHERE EXISTS (SELECT *
FROM TempLimits AS TL
WHERE TL.relid = relid AND
TL.prodid = prodid AND
TL.maxdays <= days)
John, when you say "TL.relid = relid", does not the prefix-less "relid"
refer to TempLimits?


Nice catch Erland, yes, those columns not prefixed should refer to the
table to update, Limits, and therefore should be qualified accordingly, e.g.,
TL.relid = Limits.relid.
Also, I am afraid that this is not going to perform overly well, since
SQL Server will resolve the same condition thrice. It is usually better
to have a derived table. If I understand this right it would be:

CREATE TABLE Limits
(
relid INT NOT NULL,
prodid INT NOT NULL,
days INT NOT NULL,
amt1 INT NOT NULL,
amt2 INT NOT NULL,
PRIMARY KEY (relid, prodid, days)
)

CREATE TABLE Templimits
(
relid INT NOT NULL,
prodid INT NOT NULL,
maxdays INT NOT NULL,
amt1 INT NOT NULL,
amt2 INT NOT NULL,
PRIMARY KEY (relid, prodid, maxdays)
)

INSERT Limits VALUES (148, 2, 30, 15000, 30000)
INSERT Limits VALUES (148, 2, 7, 1000, 2500)

INSERT Templimits VALUES (148, 2, 1, 7500, 1000)
INSERT Templimits VALUES (148, 2, 7, 17500, 500)
INSERT Templimits VALUES (148, 2, 30, 2500, 2000)
INSERT Templimits VALUES (148, 2, 90, 25000, 750)
INSERT Templimits VALUES (148, 2, 180, 7500, -300)

UPDATE Limits
SET amt1 = L.amt1 + coalesce(d.amt1 , 0),
amt2 = L.amt2 + coalesce(d.amt2 , 0)
FROM Limits L
JOIN (SELECT TL.relid, TL.prodid, L1.days,
amt1 = SUM(TL.amt1), amt2 = SUM(TL.amt2)
FROM Templimits TL
JOIN Limits L1 ON L1.relid = TL.relid
AND L1.prodid = TL.prodid
AND TL.maxdays <= L1.days
GROUP BY TL.relid, TL.prodid, L1.days) AS d
ON d.relid = L.relid
AND d.prodid = L.prodid
AND d.days = L.days
go
select * from Limits
go
drop table Limits, Templimits
I like to stick with Standard SQL where possible and stay away from
T-SQL proprietary constructs like this form of UPDATE. However,
one has to be pragmatic and I might give up a little purity if performance
was atrocious.

Staying pure and depending on the data, I might also try:

UPDATE Limits
SET amt1 = amt1 + (SELECT COALESCE(SUM(am t1), 0)
FROM TempLimits AS TL
WHERE TL.relid = Limits.relid AND
TL.prodid = Limits.prodid AND
TL.maxdays <= Limits.days),
amt2 = amt2 + (SELECT COALESCE(SUM(am t2), 0)
FROM TempLimits AS TL
WHERE TL.relid = Limits.relid AND
TL.prodid = Limits.prodid AND
TL.maxdays <= Limits.days)

--
JAG
--
Erland Sommarskog, SQL Server MVP, so****@algonet. se

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techinf...2000/books.asp

Jul 20 '05 #5
Why not use a function ?

CREATE FUNCTION sumLimitAmt (@Amt_Num int)
RETURNS int
AS
BEGIN
DECLARE @RtnValue int

if(@Amt_Num = 1)

SELECT @RtnValue = SUM(l.amt1)
FROM Limits l
INNER JOIN TempLimits tl
ON (
l.relid = tl.relid AND
l.prodid = tl.prodid
)
WHERE tl.maxdays <= l.days

if(@Amt_Num = 2)

SELECT @RtnValue = SUM(l.amt2)
FROM Limits l
INNER JOIN TempLimits tl
ON (
l.relid = tl.relid AND
l.prodid = tl.prodid
)
WHERE tl.maxdays <= l.days

RETURN(@RtnValu e)
END
go

UPDATE Limits
SET amt1 = amt1 + dbo.sumLimitAmt (1),
amt2 = amt2 + dbo.sumLimitAmt (2)
--select dbo.sumLimitAmt (1)
--select dbo.sumLimitAmt (2)
Michael D.
Jul 20 '05 #6
Michael D (so*****@yahoo. com) writes:
Why not use a function ?

CREATE FUNCTION sumLimitAmt (@Amt_Num int)
RETURNS int


I guess since John wanted to stick to standard SQL, that function
are out of the question.

Also, putting a scalar function is definitely not going to address
the performance problem that the original poster appeared to have,
but instead could aggrevate them quite a bit.

--
Erland Sommarskog, SQL Server MVP, so****@algonet. se

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techinf...2000/books.asp
Jul 20 '05 #7
Yes.. use of a function is ruled out since it would be a hit on
performance...

I finally had to use a query that was very much similar to the solution
from Erland.

Thanks for all your input, guys.

*** Sent via Developersdex http://www.developersdex.com ***
Don't just participate in USENET...get rewarded for it!
Jul 20 '05 #8

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

Similar topics

5
1877
by: Haisoo Shin | last post by:
Hello.. I am working on a PHP/PEAR web page that shows statistics of how many people read a certain article during given period of time. I have, say, two tables called 'books' and 'logs'. The 'books' table has fields named 'bookNo', 'bookName', and so on, and 'logs' table has fields named 'bookNo', and 'time'. Whenever somebody accesses a book, I insert a row to the 'logs' table with 'INSERT INTO logs VALUES ($no, NOW());'
2
4578
by: lev | last post by:
CREATE TABLE . ( NULL , , (44) ) ID is non-unique. I want to select all IDs where the last entry for that ID is of type 11.
7
9227
by: Andrew Mayo | last post by:
Here's a really weird one for any SQL Server gurus out there... We have observed (SQL Server 2000) scenarios where a stored procedure which (a) begins a transaction (b) inserts some rows into a table (c) re-queries another table using a subquery which references the inserted table (correlated or not)
5
6409
by: Zero.NULL | last post by:
My multiple level nested corelated query is not fetching correct result. It work fine on small set of data, but fails on larger set of data. Any clue? Explaining data storing and discussing design would be tough for me here, still to show you how complex I have created my life, here is the query: select (
0
563
by: Greg Stark | last post by:
Postgresql 7.4b2 (approximately, compiled out of CVS) When I have a subquery that has a complex subquery as one of the result columns, and then that result column is used multiple times in the parent query, the subquery is inlined for each one. This means multiple redundant executions of the subquery. I recall there was a way to defeat this optimization involving introducing an extra subquery layer somewhere. But I'm failing to be able...
8
5107
by: Venkata C | last post by:
Hi! Does anyone here know of a way to goad DB2 into converting a correlated subquery to a non-correlated one? Does DB2 ever do such a conversion? We have a query of the form SELECT .. FROM A WHERE EXISTS (SELECT 'X' FROM B, C WHERE B.COL1 = A.COL1 AND B.COL2 = A.COL2
3
4043
by: audj | last post by:
Hello, I am trying to use a subquery to avoid duplicate entries when someone submits a form to subscribe to a mailing list. So I want to check if the email exists before adding the record. I tried something like: INSERT INTO mailing_list (ID,Email) VALUES ('','$Email') WHERE NOT EXISTS (SELECT * FROM mailing_list WHERE Email LIKE '$Email'') Using NOT IN and various other structures, but keep receiving mysql errors.
5
8036
by: Anne | last post by:
Hello! Here is the statement in question: --STATEMENT A SELECT * FROM dbo.myTable WHERE colX in (SELECT colX FROM dbo.sourceTable) The problem with Statement A is that 'colX' does not exist in 'dbo.sourceTable'. It does, however, certainly exist in 'dbo.myTable'. Breaking the statement down, we have:
1
4169
by: jcf378 | last post by:
Hi all-- Does anyone have any insight as to how I might create a search form that allows a user to select criteria based on any related table in the whole database. The search form I have now only allows me to filter based on variables in a single table. I would like to have a search form where I can select multiple variables (from various linked tables) to filter by, and return results based on this multi-table filter. Allen Browne...
0
9621
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10106
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10039
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
9914
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
8937
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
7463
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
5355
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5484
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
3
2852
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.