我正在尝试使用左连接来连接两个表.结果集必须只包含"右"连接表中的第一条记录.
可以说我有两张表A和B如下;
表"A"
code | emp_no
101 | 12222
102 | 23333
103 | 34444
104 | 45555
105 | 56666
Run Code Online (Sandbox Code Playgroud)
表"B"
code | city | county
101 | Glen Oaks | Queens
101 | Astoria | Queens
101 | Flushing | Queens
102 | Ridgewood | Brooklyn
103 | Bayside | New York
Run Code Online (Sandbox Code Playgroud)
预期产出:
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
Run Code Online (Sandbox Code Playgroud)
如果你注意到我的结果在左连接之后只有表"B"中的一个匹配记录(无论匹配什么记录)(并且它是一对多的映射)
我需要从表B中选择第一个匹配的记录并忽略所有其他行.
请帮忙!
谢谢
rua*_*akh 34
玩了一下之后,事实证明这比我想象的要复杂!假设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
)
;
Run Code Online (Sandbox Code Playgroud)
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
;
Run Code Online (Sandbox Code Playgroud)
这导致左连接到不确定的第一匹配记录.我的测试显示它比任何其他发布的解决方案更快(在MS SQL Server 2012上).
最高投票的答案对我来说似乎不正确,而且似乎过于复杂.只需按子查询中表B上的代码字段进行分组,然后选择每个分组的最大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)
Run Code Online (Sandbox Code Playgroud)
如果您使用的是 SQL Server 2005 或更高版本,您可以使用排名来实现您想要的。特别是,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
Run Code Online (Sandbox Code Playgroud)
或者
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
Run Code Online (Sandbox Code Playgroud)
方法如下:
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]
Run Code Online (Sandbox Code Playgroud)
嘿,如果城市和县是唯一的,那就使用它们
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)
Run Code Online (Sandbox Code Playgroud)
但关键是您必须在其中放置一些表达式来告诉查询处理器“ first”意味着什么。
| 归档时间: |
|
| 查看次数: |
67512 次 |
| 最近记录: |