views:

56

answers:

5

I am trying to get only records that are the min date of the orderID

I have the following setup:

select
op.OrderID,
op.id,
MIN(op.Date) AS Date
From OrderPermits op
GROUP BY 
Op.OrderId
op.id,
MIN(op.Date) AS Date

Orders has 1 to many order permits.

The problem here is that I am still getting duplicate order Id's when I only want the 1 order ID that is the min(date) for order permits???

Thanks

+4  A: 
WITH    q AS
        (
        SELECT  *, ROW_NUMBER() OVER (PARTITION BY OrderID ORDER BY Date) AS rn
        FROM    orderpermits
        )
SELECT  *
FROM    q
WHERE   rn = 1

This is guaranteed to return one record per OrderID, even in case of ties on MIN(Date).

You may want to read this article:

Quassnoi
To complex for such a trivial problem.
Yves M.
@Yves: could you please describe a flaw in my approach?
Quassnoi
No flaw. It's the fastest version. Sorry that you didn't catch my ironie...
Yves M.
@Yves: why, I did, your downvote was very ironic!
Quassnoi
Erm. Sorry. Was not my intention to ruin your day.
Yves M.
@Yves: no problem. It takes three to five downvotes to ruin my day, anyway.
Quassnoi
+1  A: 

You need to specify a WHERE clause:

SELECT
   op.OrderID, op.id, op.Date
FROM
   dbo.OrderPermits op
WHERE
   op.Date = (SELECT MIN(op.Date) FROM dbo.OrderPermits WHERE OrderId = op.OrderId)
marc_s
The @op wants to get rid of the duplicates on `OrderID`, not `id`.
Quassnoi
@Quassnoi: ah, yes - good catch - thanks! Updated my answer
marc_s
@marc_s: Why there is a `GROUP BY` here?
Quassnoi
@Quassnoi: where?? :-)
marc_s
@marc_s: oh, nevermind. Must have confused you with someone else.
Quassnoi
A: 

Can't try it now but shouln't you remove teh MIN(op.Date) from the group by clause ?

Edelcom
+2  A: 

I think you are looking for this:

select op.Date, op.OrderID, op.opid
from (
    select OrderID, MIN(Date) AS MinDate 
    From OrderPermits  
    GROUP BY OrderId 
) opm
inner join OrderPermits op on opm.OrderID = op.OrderID 
    and opm.MinDate = op.Date
RedFilter
This will return duplicates in case of ties on `MIN(date)`.
Quassnoi
@Quassnoi: Agreed, it is up to the OP to decide whether this is acceptable with his/her particular data set.
RedFilter
A: 

Assuming that (except for the multiple returns) your query does what you want...

select
op.OrderID,
op.id,
MIN(op.Date) AS Date
From OrderPermits op
Where op.Date = (Select Min(Date) from OrderPermits) // <-- Add this
GROUP BY
op.OrderID,
op.id,
MIN(op.Date) as Date

Though, if you only want one record returned, you could also do:

Select op.OrderID,
  op.Id,
  op.Date
From OrderPermits op
Where op.Date = (Select MIN(Date) from OrderPermits)

These will both still return multiple results if multiple records share the MIN(Date). I do not know if that is possible with your data or not.

AllenG