Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion Groups
DB Engine
SQL ServerMSDESQL Server CE
Services
Analysis (Data Mining)Analysis (OLAP)DTSIntegration ServicesNotification ServicesReporting Services
Programming
CLRConnectivitySQLXML
Other Technologies
ClusteringEnglish QueryFull-Text SearchReplicationService Broker
General
Data WarehousingPerformanceSecuritySetupSQL Server ToolsOther SQL Server Topics
DirectoryUser Groups
Related Topics
MS AccessOther DB ProductsMS Server Products.NET DevelopmentVB DevelopmentJava DevelopmentMore Topics ...

SQL Server Forum / DB Engine / SQL Server / April 2008

Tip: Looking for answers? Try searching our database.

JOINing on derived tables?

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Maury Markowitz - 30 Apr 2008 16:02 GMT
I have an UPDATE query that sets a "quantity" field in a table based
on the sum of events in another table. Those events are "basketed"
into different accounts through a four-way tupple,  (acctId, portcode,
mgrgpcode, invpgm).

UPDATE requires the use of a derived table when using aggregates, fair
enough. The problem is that the interior derived table query is very
expensive, yet only a few rows of the returned recordset match in the
outer table. Without artificial limits, the query takes on the order
of 30 seconds, when the entire query batch otherwise takes about 5 to
10.

Here is the query in question (tpPNL means "temporary profit 'n
loss") . tpHPL already contains a number of rows for various accounts,
ONE of these rows is in an account that needs the complex calculation
of the inner query. Yet when the query runs, it does so for every
record in tblTrades, which has 2 million+ rows. I have artificially
introduced a WHERE constraint to limit this down for testing purposes,
but this is far from ideal. What should happen is that the inner query
will return one row for every (acctId, portcode, mgrgpcode, invpgm)
tupple in the outer table (tpHPL).

I realize I can do another sub-select on tpHPL and return a list of
which of those tupples is being used, but this strikes me as yet
another performance hit. Is there some easy way to have the inner
JOINed on the outer so this "just happens"?

UPDATE tpPNL SET
openingMVLocalCcy = s.openingMV,
closingMVLocalCcy = s.closingMV,
openingMVAcctCcy = s.openingMV * h.openingFX,
closingMVAcctCcy = s.closingMV * h.closingFX
FROM tpPNL h JOIN
(SELECT acctId, portcode, mgrgpcode, invpgm,
SUM(
 CASE
  WHEN TranDate>@startDate THEN 0
  ELSE amount
 END) as openingMV,
SUM(
 CASE
  WHEN TranDate>@endDate THEN 0
  ELSE amount
 END) as closingMV
FROM tblTrades
WHERE deleted=0
AND portcode=400
GROUP BY acctId, portcode, mgrgpcode, invpgm) as s
ON s.acctId=h.accountId AND s.portcode=h.portfolioId AND
s.mgrgpcode=h.groupId
Roy Harvey (SQL Server MVP) - 30 Apr 2008 16:41 GMT
I would write an EXISTS test in the subquery that checks for matches
in tpHPL.  If there are really as few matches as you say it should pay
off.  Alternately, it might be possible to simply JOIN tblTrades and
tpHPL in the subquery, though that would only work if the set of join
columns constitutes the full key to tpHPL.

Not that it sounds like you need me to tell you how to do that, just
saying that is what I would do.

Roy Harvey
Beacon Falls, CT

>I have an UPDATE query that sets a "quantity" field in a table based
>on the sum of events in another table. Those events are "basketed"
[quoted text clipped - 46 lines]
> ON s.acctId=h.accountId AND s.portcode=h.portfolioId AND
>s.mgrgpcode=h.groupId
Maury Markowitz - 30 Apr 2008 19:28 GMT
On Apr 30, 11:41 am, "Roy Harvey (SQL Server MVP)"
<roy_har...@snet.net> wrote:
> off.  Alternately, it might be possible to simply JOIN tblTrades and
> tpHPL in the subquery, though that would only work if the set of join
> columns constitutes the full key to tpHPL.

Can you give me a simple example of this? I was thinking of something
like...

WHERE acctId IN (select distinct acctId from tpHPL)
  AND portcode IN (select distinct portfolio from tpHPL)

but that seems expensive!

Maury
Roy Harvey (SQL Server MVP) - 30 Apr 2008 21:04 GMT
Your approach of using two independent IN clauses is incorrect.
Imagine that we had two rows of data in tpHPL:

acctId       portcode
ABC          XYZ
BCD          MNO

Using two independent IN clauses that would match any of four
combinations:

ABC          XYZ
ABC          MNO
BCD          MNO
BCD          XYZ

What I suggest instead is to use an EXISTS test in the subquery.

UPDATE tpPNL
  SET openingMVLocalCcy = s.openingMV,
      closingMVLocalCcy = s.closingMV,
      openingMVAcctCcy = s.openingMV * h.openingFX,
      closingMVAcctCcy = s.closingMV * h.closingFX
 FROM tpPNL h
 JOIN (SELECT acctId, portcode, mgrgpcode, invpgm,
              SUM(CASE WHEN TranDate > @startDate
                       THEN 0
                       ELSE amount
                  END) as openingMV,
              SUM(CASE WHEN TranDate > @endDate
                       THEN 0
                       ELSE amount
                  END) as closingMV
         FROM tblTrades
        WHERE deleted = 0
          AND portcode = 400
          AND EXISTS
              (SELECT * FROM tpPNL as X
                WHERE tblTrades.acctId = X.accountId
                  AND tblTrades.portcode = X.portfolioId
                  AND tblTrades.mgrgpcode = X.groupId)
        GROUP BY acctId, portcode, mgrgpcode, invpgm) as s
   ON s.acctId = h.accountId
  AND s.portcode = h.portfolioId
  AND s.mgrgpcode = h.groupId

Roy Harvey
Beacon Falls, CT

>On Apr 30, 11:41 am, "Roy Harvey (SQL Server MVP)"
><roy_har...@snet.net> wrote:
[quoted text clipped - 11 lines]
>
>Maury
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.