如何从第一个表中选择所有记录,只从第二个表中选择第一个匹配的记录?

时间:2015-08-05 20:03:32

标签: sql sql-server

从这两个表中

FirstTable
Number|
  1   |
  2   |
  3   |
  4   |

SecondTable
Id | Number | Column2 | Column3
--------------------------------
1  |  1     | text1   | text11
2  |  2     | text2   | text12
3  |  3     | text3   | text13
4  |  3     | text4   | text14
5  |  2     | text5   | text15

如何从第一个表中选择所有记录,并且只从第二个表中选择第一个与空值匹配的记录? 结果应该是这样的:

Result
Number | Column2 | Column3
--------------------------
 1     | text1   | text11
 2     | text2   | text12
 3     | text3   | text13
 4     | null    | null

我试过了:

SELECT FT.Number, ST.Column2, ST.Column3
FROM FirstTable FT LEFT JOIN 
SecondTable ST ON FT.Number = 
(
    SELECT TOP 1 S2.Number FROM SecondTable S2 WHERE S2.Number = FT.Number
)

SELECT min(FT.Number), ST.Column2, ST.Column3
FROM FirstTable FT LEFT JOIN 
SecondTable ST ON FT.Number = ST.Number
GROUP BY ST.Column2, ST.Column3

2 个答案:

答案 0 :(得分:4)

您可以在子查询中使用Row_Number()执行此操作,如下所示:

SELECT T1.Number, T2.Column1, T2.Column3 
FROM FirstTable T1
LEFT JOIN ( SELECT ID, NUMBER, Colunmn2, Column3,
              ROW_NUMBER() OVER (PARTITION BY Number ORDER BY ID ASC) as NumOrder
            FROM SecondTable
) T2 ON T1.Number = T2.Number AND T2.NumOrder = 1

如果只运行子查询,您将看到它是如何工作的 - 它通过值为1来“标记”感兴趣的行。然后一个简单的连接起作用。

答案 1 :(得分:1)

你可以做第一次尝试的这种变化:

SELECT FT.Number, ST.Column2, ST.Column3
FROM FirstTable FT LEFT JOIN 
SecondTable ST ON ST.Id = 
(
    SELECT TOP 1 S2.Id FROM SecondTable S2 WHERE S2.Number = FT.Number
    ORDER BY S2.Id
)

编辑:

我将以下脚本作为测试运行:

DECLARE @FirstTable TABLE (
  [Number] int
);

DECLARE @SecondTable TABLE (
    Id int IDENTITY(1,1)
,   Number int
,   Column2 varchar(31)
,   Column3 varchar(31)
)

INSERT INTO @FirstTable (Number) VALUES (1), (2), (3), (4);

INSERT INTO @SecondTable (Number, Column2, Column3) VALUES
    (1, 'text1', 'text11')
,   (2, 'text2', 'text12')
,   (3, 'text3', 'text13')
,   (3, 'text4', 'text14')
,   (2, 'text5', 'text15')
;

SELECT FT.Number, ST.Column2, ST.Column3
FROM @FirstTable FT LEFT JOIN 
@SecondTable ST ON ST.Id = 
(
    SELECT TOP 1 S2.Id FROM @SecondTable S2 WHERE S2.Number = FT.Number
    ORDER BY S2.Id
);

我得到了以下结果:

Number  Column2 Column3
1           text1   text11
2           text2   text12
3           text3   text13
4           NULL    NULL

这正是您期望的结果。如果你得到太多行"你必须在实施中犯了错误。