Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 获取联接表的顶行_Sql_Sql Server_Sql Server 2012 - Fatal编程技术网

Sql 获取联接表的顶行

Sql 获取联接表的顶行,sql,sql-server,sql-server-2012,Sql,Sql Server,Sql Server 2012,我有两张桌子,表A和表B tableA - id int name varchar(50) tableB - id int fkid int name varchar(50) 这两个表在id和fkid之间联接 下面是表A中的示例行 下面是表B的输出 我想联接两个表,只得到联接表的最上面一行。因此,输出将如下所示 Id Name fkid 1 P1 1 2

我有两张桌子,表A和表B

tableA - id int
         name varchar(50)

tableB - id int
         fkid int
         name varchar(50)
这两个表在id和fkid之间联接

下面是表A中的示例行

下面是表B的输出

我想联接两个表,只得到联接表的最上面一行。因此,输出将如下所示

Id          Name         fkid
 1          P1              1
 2          P2              4
 3          P3            null
这是

如何通过单个查询实现这一点?我知道我可以在.net代码中循环并检索最上面的行。但我希望它在一个查询中

您可以这样做:

;WITH CTE
AS
(
    SELECT
        ROW_NUMBER() OVER(PARTITION BY fkID ORDER BY ID) AS RowNbr,
        tableB.*
    FROM
        tableB
)
SELECT
    *
FROM
    tableA
    LEFT JOIN CTE
        ON CTE.fkID=tableA.id
        AND CTE.RowNbr=1

或者没有窗口功能。像这样:

SELECT
    *
FROM
    tableA
    LEFT JOIN 
    (
        SELECT
            ROW_NUMBER() OVER(PARTITION BY fkID ORDER BY ID) AS RowNbr,
            tableB.*
        FROM
            tableB
    ) as tbl
    ON tbl.fkID=tableA.id
    AND tbl.RowNbr=1

更新:

我选择使用row_number的原因是,如果表B中有更多的列,那么示例就是这样。如果您想显示更多的列,则不需要额外的聚合。就我个人而言,更清楚的是,在ID上有一个订单,您可以这样做:

;WITH CTE
AS
(
    SELECT
        ROW_NUMBER() OVER(PARTITION BY fkID ORDER BY ID) AS RowNbr,
        tableB.*
    FROM
        tableB
)
SELECT
    *
FROM
    tableA
    LEFT JOIN CTE
        ON CTE.fkID=tableA.id
        AND CTE.RowNbr=1
select ta.id, ta.name, min(tb.id) from tableA ta
left join tableB tb on tb.fkid=ta.id
group by ta.id, ta.name

或者没有窗口功能。像这样:

SELECT
    *
FROM
    tableA
    LEFT JOIN 
    (
        SELECT
            ROW_NUMBER() OVER(PARTITION BY fkID ORDER BY ID) AS RowNbr,
            tableB.*
        FROM
            tableB
    ) as tbl
    ON tbl.fkID=tableA.id
    AND tbl.RowNbr=1

更新:


我选择使用row_number的原因是,如果表B中有更多的列,那么示例就是这样。如果您想显示更多的列,则不需要额外的聚合。就我个人而言,ID上的order by更为清晰。

由@Danila编写的查询更为简单。是否有使用行号的具体原因?您的查询也给出了正确的答案output@Happy:更新了答案否没有更多列。另外,将查询转换为linq也有点困难。您认为将查询转换为linq容易吗?@Danila编写的查询更简单。是否有使用行号的具体原因?您的查询也给出了正确的答案output@Happy:更新了答案否没有更多列。另外,将查询转换为linq也有点困难。您认为将查询转换为linq容易吗?您想要最上面一行是什么意思?您已经显示了预期的输出,其中有3行而不是1行,那么您到底想要什么?@DanielAndréI说连接表的第一行,而不是只有1行的整个输出。您想要第一行是什么意思?“您已经用3行而不是1行显示了预期的输出,那么您到底想要什么?”DanielAndréI说,连接表的第一行并不是只有1行的整个输出
select ta.id, ta.name, min(tb.id) from tableA ta
left join tableB tb on tb.fkid=ta.id
group by ta.id, ta.name