Select first record in a One-to-Many relation using left join

后端 未结 7 1228
予麋鹿
予麋鹿 2020-12-02 16:52

I\'m trying to join two tables using a left-join. And the result set has to include only the first record from the \"right\" joined table.

Lets say I have two tables

相关标签:
7条回答
  • 2020-12-02 17:12

    In Oracle you can do:

    WITH first_b AS (SELECT code, min(rowid) AS rid FROM b GROUP BY code)) 
    SELECT a.code, a.emp_no, b.city, b.county
    FROM a 
    INNER JOIN first_b 
     ON first_b.code = a.code
    INNER JOIN b
     ON b.rowid = first_b.rid
    
    0 讨论(0)
  • 2020-12-02 17:16

    I modified the answer from ruakh and this seem to work perfectly with mysql.

    SELECT 
       table_a.code,
       table_a.emp_no,
       table_b.city,
       table_b.county
    FROM table_a a
    LEFT JOIN table_b b
    ON b.code = a.code 
    AND b.id = (  SELECT id FROM table_b 
                  WHERE table_b.code = table_a.code 
                  LIMIT 1
               )
    ;
    
    0 讨论(0)
  • 2020-12-02 17:32

    If you are on SQL Server 2005 or later version, you could use ranking to achieve what you want. In particular, ROW_NUMBER() seems to suit your needs nicely:

    WITH B_ranked AS (
      SELECT
        *,
        rnk = ROW_NUMBER() OVER (PARTITION BY code ORDER BY city)
      FROM B
    )
    SELECT
      A.code,
      A.emp_no,
      B.city,
      B.county
    FROM A
      LEFT JOIN B_ranked AS B ON A.code = B.code AND b.rnk = 1
    

    OR

    WITH B_unique_code AS (
      select * from(
         SELECT
          *,
          rnk = ROW_NUMBER() OVER (PARTITION BY code ORDER BY city)
          FROM B
         ) AS s
      where rnk = 1
    )
    SELECT
      A.code,
      A.emp_no,
      B.city,
      B.county
    FROM A
      LEFT JOIN B_unique_code AS B ON A.code = B.code
    
    0 讨论(0)
  • 2020-12-02 17:33

    After playing around a bit, this turns out to be trickier than I'd expected! Assuming that table_b has some single column that is unique (say, a single-field primary key), it looks like you can do this:

    SELECT table_a.code,
           table_a.emp_no,
           table_b.city,
           table_b.county
      FROM table_a
      LEFT
      JOIN table_b
        ON table_b.code = table_a.code
       AND table_b.field_that_is_unique =
            ( SELECT TOP 1
                     field_that_is_unique
                FROM table_b
               WHERE table_b.code = table_a.code
           )
    ;
    
    0 讨论(0)
  • 2020-12-02 17:37

    Another option: OUTER APPLY

    If supported by the database, OUTER APPLY is an efficient and terse option.

    SELECT *
    FROM 
        Table_A a
    OUTER APPLY
        (SELECT TOP 1 * 
        FROM Table_B b_1
        WHERE b_1.code = a.code
        ) b
    ;
    

    This results in a left join to the indeterminate first matched record. My tests show it to be quicker than any other posted solution (on MS SQL Server 2012).

    0 讨论(0)
  • 2020-12-02 17:37

    this is how:

     Select * From TableA a
         Left Join TableB b
             On b.Code = a.Code 
                 And [Here put criteria predicate that 'defines' what the first record is]
    

    Hey, if the city and county are unique, then use them

       Select * From TableA a
         Left Join TableB b
             On b.Code = a.Code 
                 And b.City + b.county =
                      (Select Min(city + county)
                       From TableB 
                       Where Code = b.Code)
    

    But the point is you have to put some expression in there to tell the query processor what it means to be first.

    0 讨论(0)
提交回复
热议问题