从这两个表中
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
答案 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
这正是您期望的结果。如果你得到太多行"你必须在实施中犯了错误。