Home > Back-end >  Rewrite a sql query for better optimization
Rewrite a sql query for better optimization

Time:10-16

I have a table that has the following data

id orderid
1 0
1 1
1 2
2 0
3 0
3 1

An id can have multiple order ids. If an id has only a single row with orderid 0 then it indicates that the order is not placed yet. I have find all the ids for which orders are not placed yet.

Here's what I came up with

Select *
From (
    Select
      id,
      orderId,
      Count(id) Over (partition by id) 'cntId'
    From table
) a
Where a.cntId = 1
and a.Orderid = 0

Is there a better way to write this query? I would appreciate any help.

CodePudding user response:

You could try it like this

SELECT id
FROM yourTable
GROUP BY id
HAVING count(*)=1
       and max(orderid)=0;

CodePudding user response:

If you want to go the aggregation approach, I prefer:

SELECT id
FROM yourTable
GROUP BY id
HAVING MIN(orderid) = MAX(orderid) AND MIN(orderid) = 0;

This query should benefit from an index on (id, groupid).

My answer doesn't select the groupid value, but we already know that this value would have to be zero for the entire result set.

CodePudding user response:

If you KNOW the sequential ordering of the / order IDs will always be 0, 1, 2, etc, and you have an index on (id, orderid), I would self-join for so it does not need to query for those IDs that may have 100 orders

select
      yt.id
   from
      YourTable yt
         LEFT JOIN YourTable yt2
            on yt.id = yt2.id
           and yt2.orderid = 1
   where
          yt.orderid = 0
      AND yt2.id is null

So it will only ever care about an order ID = 0 or 1 and return only those where no orderID = 1 is found.

  • Related