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+17500+2500) 33500
(30000+1000+500+2000)
148 2 7 26000 (1000+7500+17500) 4000
(2500+1000+500)
************************************************** **************************
Here is the query that I have right now...
update Limit
set Amt1 = isnull(Amt1,0) + IsNull(temptable.temp_Amt1, 0)
, Amt2 = isnull(Amt2,0) + IsNull(temptable.temp_Amt2, 0)
from Limit inner join
(
select Templimits.relationship_id relationship_id,
Templimits.product_id product_id, sum(Templimits.Amt1) temp_Amt1,
sum(Templimits.Amt2) temp_Amt2
from TempLimits
WHERE TEMPLIMITS.MAXDAYS <= LIMIT.DAYS
group by limit.relationship_id, limit.product_id
) temptable
on Limit.relid = temptable.relid and
Limit.prodid = temptable.prodid
************************************************** ****************************
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 7 3984
"Kannan" <pv*******@yahoo.com> wrote in message
news:b4*************************@posting.google.co m... 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+17500+2500) 33500 (30000+1000+500+2000) 148 2 7 26000 (1000+7500+17500) 4000 (2500+1000+500)
************************************************** ************************** Here is the query that I have right now...
update Limit set Amt1 = isnull(Amt1,0) + IsNull(temptable.temp_Amt1, 0) , Amt2 = isnull(Amt2,0) + IsNull(temptable.temp_Amt2, 0) from Limit inner join ( select Templimits.relationship_id relationship_id, Templimits.product_id product_id, sum(Templimits.Amt1) temp_Amt1, sum(Templimits.Amt2) temp_Amt2 from TempLimits WHERE TEMPLIMITS.MAXDAYS <= LIMIT.DAYS group by limit.relationship_id, limit.product_id ) temptable on Limit.relid = temptable.relid and Limit.prodid = temptable.prodid
************************************************** **************************** 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
Kannan (pv*******@yahoo.com) writes:
************************************************** ************************** Here is the query that I have right now...
update Limit set Amt1 = isnull(Amt1,0) + IsNull(temptable.temp_Amt1, 0) , Amt2 = isnull(Amt2,0) + IsNull(temptable.temp_Amt2, 0) from Limit inner join ( select Templimits.relationship_id relationship_id, Templimits.product_id product_id, sum(Templimits.Amt1) temp_Amt1, sum(Templimits.Amt2) temp_Amt2 from TempLimits WHERE TEMPLIMITS.MAXDAYS <= LIMIT.DAYS group by limit.relationship_id, limit.product_id ) temptable on Limit.relid = temptable.relid and Limit.prodid = temptable.prodid
************************************************* **************************
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
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
"Erland Sommarskog" <so****@algonet.se> wrote in message news:Xn********************@127.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(amt1), 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(amt2), 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
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(@RtnValue)
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.
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
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! This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
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...
|
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.
|
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...
|
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...
|
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...
|
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...
|
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.
...
|
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...
|
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...
|
by: taylorcarr |
last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
|
by: aa123db |
last post by:
Variable and constants
Use var or let for variables and const fror constants.
Var foo ='bar';
Let foo ='bar';const baz ='bar';
Functions
function $name$ ($parameters$) {
}
...
|
by: ryjfgjl |
last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
|
by: BarryA |
last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
|
by: Sonnysonu |
last post by:
This is the data of csv file
1 2 3
1 2 3
1 2 3
1 2 3
2 3
2 3
3
the lengths should be different i have to store the data by column-wise with in the specific length.
suppose the i have to...
|
by: Hystou |
last post by:
There are some requirements for setting up RAID:
1. The motherboard and BIOS support RAID configuration.
2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
|
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,...
|
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,...
|
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...
| |