Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQL: Inner Join return one row based on criteria

This is probably simple, but i'm looking for the raw SQL to perform an INNER JOIN but only return one of the matches on the second table based on criteria.

Given two tables:

**TableOne**   
 ID  Name  
 1   abc  
 2   def

**TableTwo**  
 ID    Date     
 1     12/1/2014
 1     12/2/2014
 2     12/3/2014
 2     12/4/2014
 2     12/5/2014

I want to join but only return the latest date from the second table:

Expected Result:
1   abc   12/2/2014
2   def   12/5/2014

I can easily accomplish this in LINQ like so:

TableOne.Select(x=> new { x.ID, x.Name, Date = x.TableTwo.Max(y=>y.Date) });

So in other words, what does the above LINQ statement translate into in raw SQL?

like image 381
stedrolln34 Avatar asked Dec 31 '14 20:12

stedrolln34


People also ask

How do I return only one row in SQL?

To return only the first row that matches your SELECT query, you need to add the LIMIT clause to your SELECT statement. The LIMIT clause is used to control the number of rows returned by your query. When you add LIMIT 1 to the SELECT statement, then only one row will be returned.

Does inner join return multiple rows?

Summary. Inner Join can for sure return more records than the records of the table. Inner join returns the results based on the condition specified in the JOIN condition. If there are more rows that satisfy the condition (as seen in query 2), it will return you more results.

Can I use where clause in inner join?

To use the WHERE clause to perform the same join as you perform using the INNER JOIN syntax, enter both the join condition and the additional selection condition in the WHERE clause. The tables to be joined are listed in the FROM clause, separated by commas.


1 Answers

There are two ways to do this:

  1. Using GROUP BY and MAX():

    SELECT one.ID,
           one.Name,
           MAX(two.Date)
        FROM TableOne one
            INNER JOIN TableTwo two on one.ID = two.ID
        GROUP BY one.ID, one.Name
    
  2. Using ROW_NUMBER() with a CTE:

    ; WITH cte AS (
        SELECT one.ID,
           one.Name,
           two.Date,
           ROW_NUMBER() OVER (PARTITION BY one.ID ORDER BY two.Date DESC) as rn
        FROM TableOne one
           INNER JOIN TableTwo two ON one.ID = two.ID
    )
        SELECT ID, Name, Date FROM cte WHERE rn = 1
    
like image 66
Rhumborl Avatar answered Sep 23 '22 03:09

Rhumborl