Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Forcing left join to only return one row from matching Ids in the right table

I have two tables in which I'd like to join, the right table sometimes has more than 1 row for each ID. But I'm not interested to have all the matches, only the first one is enough.

How can I do that?

Example:

Foo:

     Id             FooColumns....
     100             xxxxxxxx
     200             xxxxxxxx
     300             xxxxxxxx
     400             xxxxxxxx

Bar:

     Id             BarColumns....
     100             yyyyyyyy
     100             zzzzzzzz
     200             yyyyyyyy
     200             zzzzzzzz

What I want to have is :

FooBar:

     Id             FooColumns....     BarColumns
     100             xxxxxxxx            yyyyyyyy
     200             xxxxxxxx            yyyyyyyy
     300             xxxxxxxx              nulls
     400             xxxxxxxx              nulls

Query: 
   Select F.*,B.* from Foo f left join Bar b on f.Id=B.Id   ?? 
like image 532
Ariox66 Avatar asked Aug 09 '17 10:08

Ariox66


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.

Which join returns rows when there is at least one matching row between the tables?

Introduction to SQL LEFT JOIN clause In the previous tutorial, you learned about the inner join that returns rows if there is, at least, one row in both tables that matches the join condition. The inner join clause eliminates the rows that do not match with a row of the other table.

Which type of join is used to returns all rows if there is one match in both tables * Inner join outer join full join left join?

SQL outer join On joining tables with a SQL inner join, the output returns only matching rows from both the tables.

Which type of join is used to returns all rows if there is one match in both tables?

Note: The FULL OUTER JOIN keyword returns all matching records from both tables whether the other table matches or not. So, if there are rows in "Customers" that do not have matches in "Orders", or if there are rows in "Orders" that do not have matches in "Customers", those rows will be listed as well.


1 Answers

One method uses row_number():

Select F.*, B.*
from Foo f left join
     (select b.*, row_number() over (partition by b.id order by id) as seqnum
      from bar b
     ) b
     on f.Id = B.Id and seqnum = 1; 

The order by specifies what you mean by "first". The order by id is an arbitrary ordering.

And alternative method uses outer apply:

Select F.*, B.*
from Foo f outer apply
     (select top 1 b.*
      from bar b
      where f.Id = B.Id
     ) b; 

In this case, you would add an order by to the subquery to get the "first" based on some column. Also, this should have better performance than the previous version.

like image 170
Gordon Linoff Avatar answered Sep 25 '22 12:09

Gordon Linoff