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.