使用左连接select一对多关系中的第一条logging

我试图使用左连接来连接两个表。 结果集只能包含“右”连接表中的第一条logging。

假设我有两个表A和B,如下所示;

表“A”

code | emp_no 101 | 12222 102 | 23333 103 | 34444 104 | 45555 105 | 56666 

表“B”

 code | city | county 101 | Glen Oaks | Queens 101 | Astoria | Queens 101 | Flushing | Queens 102 | Ridgewood | Brooklyn 103 | Bayside | New York 

预期产出:

 code | emp_no | city | county 101 | 12222 | Glen Oaks | Queens 102 | 23333 | Ridgewood | Brooklyn 103 | 34444 | Bayside | New York 104 | 45555 | NULL | NULL 105 | 56666 | NULL | NULL 

如果你注意到我的结果只有一个匹配来自表“B”的logging(匹配什么logging并不重要)在左连接之后(它是一对多的映射)

我需要从表B中select第一个匹配的logging,并忽略所有其他行。

请帮忙!

谢谢

玩了一下后,结果比我想象的要复杂得多! 假设table_b有一些唯一的列(比如单字段主键),看起来你可以这样做:

 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 ) ; 

另一种select: OUTER APPLY

如果数据库支持, OUTER APPLY是一个高效和简洁的选项。

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

这会导致不确定的第一个匹配logging的左连接。 我的testing显示它比任何其他发布的解决scheme(在MS SQL Server 2012上)更快。

如果您使用的是SQL Server 2005或更高版本,则可以使用排名实现您想要的function。 尤其是, ROW_NUMBER()似乎很适合你的需要:

 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 

要么

 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 

答案最高的答案似乎并不正确,似乎过于复杂。 只需按子查询中表B的代码字段进行分组,然后select每个分组的最大ID即可。

 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 IN (SELECT MAX(field_that_is_unique) FROM table_b GROUP BY table_b.code) 

我修改了从ruakh的答案,这似乎与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 ) ; 

在Oracle中你可以这样做:

 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 

这是如何:

  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] 

嘿,如果这个城市和县是独一无二的,那就用它们吧

  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) 

但关键是你必须在那里放置一些expression式来告诉查询处理器首先意味着什么。