Reputation: 417
I need to query data from two tables, one is a parent (batches) and the other a child (details), where I filter on the parent and want to return all items of the parent based on a where clause, but selectively filter different aspects of the child table into summary columns for the parent result set.
With that said, here is the query I have now that works: (sorry for the length, I stripped out some stuff that does not matter but wanted to keep the subqueries)
SELECT
workid,
siteid,
(
SELECT
top 1 description
FROM
worksrcdesc a
WHERE
a.workid = b.workid
AND
a.site = b.site
ORDER BY
date DESC
) AS descript,
itemid,
mode,
systemdate,
(
SELECT
count(sequence)
FROM
details a
WHERE
a.reject = 0
AND
a.itemid = b.itemid
AND
a.siteid = b.siteid
AND
documenttype IN (1,2)
) AS documentcount,
(
SELECT
count(sequence)
FROM
details a
WHERE
a.reject = 0
AND
a.itemid = b.itemid
AND
a.siteid = b.siteid
AND
documenttype = 15
) AS othercount,
(
SELECT
count(distinct tranno)
FROM
details a
WHERE
a.reject = 0
AND
a.itemid = b.itemid
AND
a.siteid = b.siteid
) AS transactioncount,
(
SELECT
top 1 groupnum
FROM
groups d
WHERE
b.siteid = d.siteid
AND
b.workid = d.workid
) AS sitegrouping
FROM
batches b with (nolock)
WHERE
workid IN (12345,67980)
ORDER BY
workid ASC,
itemid ASC
The batches table has 54,000 rows, which filtering by workid limits down to just 300 entries. The details table has 3.3 million rows, which gets filtered down to around 76,000 rows based on the same criteria used on batches.
Right now this takes over 4-5 seconds to run on average; is there any way to simplify this to get it running faster? I thought about doing joins instead of subqueries, but what throws me off (and I cannot get it working) is the different where clauses on the subqueries.
Upvotes: 0
Views: 174
Reputation: 12318
At least you could combine your subqueries into one outer apply:
outer apply (
SELECT
sum(case when documenttype IN (1,2) then 1 else 0 end) as documentcount,
sum(case when documenttype = 15 then 1 else 0 end) as othercount,
count(distinct tranno) as transactioncount
FROM
details a
WHERE
a.reject = 0 AND
a.itemid = b.itemid AND
a.siteid = b.siteid
)
If sequence can be null, the you might need to check it in the sum clause too.
Also indexing is important, especially if the number of rows that match is high, so that time isn't spent on key lookups. Most likely you want to have index with itemid, siteid and reject + documenttype and tranno as included columns. This of course needs consideration if the table is updated heavily.
Upvotes: 1