我正在尝试使用左连接加入两个表。结果集必须只包含“右”连接表中的第一条记录。
假设我有两张表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”中的一条匹配记录(无论匹配什么记录)(并且它是一对多的映射)
我需要从表B中选择第一个匹配的记录并忽略所有其他行。
请帮忙!
由于
答案 0 :(得分:33)
玩了一下之后,事实证明这比我想象的要复杂!假设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
)
;
答案 1 :(得分:7)
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
;
这会导致 indeterminate 第一个匹配记录的左连接。我的测试显示它比任何其他发布的解决方案更快(在MS SQL Server 2012上)。
答案 2 :(得分:6)
最高投票的答案对我来说似乎不正确,而且似乎过于复杂。 只需按子查询中表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)
答案 3 :(得分:4)
如果您使用的是SQL Server 2005或更高版本,则可以使用ranking来实现您的目标。特别是,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
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
答案 4 :(得分:2)
我修改了 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
)
;
答案 5 :(得分: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
答案 6 :(得分:0)
这是如何:
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)
但关键是你必须在那里放一些表达式来告诉查询处理器意味着 首先 。