Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Select Top 1 From a Table For Each Id in another Table

Table Structure is:

create table fruit (
  id int identity(1,1),
  name varchar(max)
)

create table fruit_allocation (
  id int identity(1,1),
  fruit_id int references fruit(id),
  customer_id int references store(id),
  amount float,
)

create table measurement (
  fruit_allocation_id int references fruit_allocation(id),
  measurement_date datetime,
  measurement float,
)

Each fruit can be allocated to more than one customer creating a fruit_allocation record. Each fruit_allocation record can have multiple measurements.

I want to select the latest measurement for each fruit_allocation given a fruit id

So far I have the following:

select * 
  from measurement 
 where fruit_allocation_id in (select id 
                                 from fruit_allocation 
                                where fruit_id = 10)

This returns all measurements for that fruit, I want to just return 1 measurement per fruit_allocation.

like image 888
Raedur Avatar asked Feb 22 '11 01:02

Raedur


People also ask

How do I pull data from one table to another table?

The INSERT INTO SELECT statement copies data from one table and inserts it into another table. The INSERT INTO SELECT statement requires that the data types in source and target tables match. Note: The existing records in the target table are unaffected.

Can we use top with Group By clause?

Typically, these are accomplished using the TOP or LIMIT clause. Problem is, Top N result sets are limited to the highest values in the table, without any grouping. The GROUP BY clause can help with that, but it is limited to the single top result for each group.


2 Answers

You can CROSS APPLY

select a.*, m.*
from fruit_allocation a
cross apply (
    select top 1 *
    from measurement m
    where m.fruit_allocation_id = a.id
    order by m.measurement_date desc
) m
where a.fruit_id = 10
like image 196
RichardTheKiwi Avatar answered Sep 21 '22 15:09

RichardTheKiwi


Assuming you are using SQL Server 2005+

With RankedMeasurements As
    (
    Select M.fruit_allocation_id
        , M.measurement_date
        , M.measurement
        , Row_Number() Over ( Partition By M.fruit_allocation_id 
                                Order By M.measurement_date Desc ) As Rnk
    From measurement As M
    Where Exists    (
                    Select 1
                    From fruit_allocation As FA1
                    Where FA1.id = M.fruit_allocation_id
                        And FA1.fruit_id = 10
                    )   
    )
Select RM.fruit_allocation_id
    , RM.measurement_date
    , RM.measurement
From RankedMeasurements As RM
Where Rnk = 1
like image 22
Thomas Avatar answered Sep 21 '22 15:09

Thomas