Reputation: 1890
The following query works, but is not particularly fast:
select distinct controlid, (
select max(Orderno) From my_table
Where ControlID = #param1#
and a = 3 and b = 13 and c = 0 and d = 0
) colA, (
Select max(Orderno) From my_table
Where ControlID = #param1#
and a = 2
) colB, (
Select max(Orderno) From my_table
Where ControlID = #param1#
and a = 1 and b = 14 and e = 1
) colC, (
Select max(Orderno) From my_table
Where ControlID = #param1#
and a = 3 and b = 13 and e = 1 and c = 0 and d = 0
) colD, (
Select a From my_table
Where ControlID = #param1#
and Orderno = #param2#
) colE
from my_table
where controlid = #param1#
The table being queried has over 300K rows, and the count of rows for a particular controlid (before the distinct clause) varies from 1 to 61. The profiler says the response time is 234/42 msecs. There are no indexes on the table.
Obviously, the lack of indexes is a problem, but beyond that, can anyone recommend a more efficient way of writing this query?
Upvotes: 1
Views: 71
Reputation: 4622
use an aggregate instead of subqueries:
select distinct controlid,
max (case when a=3 and b=13 and c=0 and d= 0 then OrderNo end) as colA,
max (case when a=2 then OrderNo end) as colB,
max (case when a=1 and b=14 and e=1 then OrderNo end) as colC,
max (case when a=3 and b=13 and e=1 and c=0 and d=0 then OrderNo end) as colD,
max (case when OrderNo=#param2# then a end) as colE
from my_table
where controlid = #param1#
group by controlid
I don't know which RDBMS you use, so the case when
construct might have to be modified to your local dialect. This one should be valid for MSSQL
UPDATE: My glasses don't work properly and so I did not notice the ORACLE tag. Embarassing...
Upvotes: 4
Reputation: 231871
You should be able to avoid hitting the table multiple times and do a single table scan
SELECT controlID,
MAX( CASE WHEN a = 3
AND b = 13
AND c = 0
AND d = 0
THEN orderNo
ELSE NULL
END) colA,
MAX( CASE WHEN a = 2
THEN orderNo
ELSE NULL
END) colB,
MAX( CASE WHEN a = 1
AND b = 14
AND e = 1
THEN orderNo
ELSE NULL
END) colC,
MAX( CASE WHEN a = 3
AND b = 13
AND e = 1
AND c = 0
AND d = 0
THEN orderNo
ELSE NULL
END) colD,
MAX( CASE WHEN orderNo = #param2#
THEN a
ELSE NULL
END) colE
FROM my_table
WHERE controlId = #param1#
GROUP BY controlID
Of course, it may well end up being more efficient to have appropriate indexes on the table and do multiple index scans. Without knowing your data, it's hard to know.
Upvotes: 3