SQL LEFT JOIN只返回第一行

14 浏览
0 Comments

SQL LEFT JOIN只返回第一行

假设我们有这样的数据集:

表:DataTable1

ID      ExperienceId   LanguageId    ...
-------------------------------------------
1       1              1
2       1              2
3       1              3
4       2              1
5       2              2
6       2              3
7       3              1
8       3              2
9       3              3
...

表:DataTable2

ID      SomeId OtherId LanguageId    ...
-------------------------------------------
1       459    1       1
2       459    1       2
3       459    1       3
4       245    2       1
5       245    2       2
6       245    2       3
7       295    3       1
8       295    3       2
9       295    3       3
...

我想连接这些表,并仅获取SomeId列,忽略LanguageId列。为了更清楚地说明:

SELECT
    t2.SomeId AS RequiredId
    -- ...主要是来自t2的其他数据
FROM DataTable1 AS t1
LEFT JOIN DataTable2 AS t2 
    ON t2.OtherId = t1.ExperienceId 
    AND t2.LanguageId = 
        (SELECT TOP 1 t1.LanguageId
         ORDER BY t1.LanguageId)

如果查询没有错误,这个查询应该返回以下行:

SomeId    ...
----------------
459       ...
245       ...
295       ...
...

现在它返回了三倍的相同数据(只有LanguageId不同)。

如果我确定它总是存在,我会尝试用WHERE t1.LanguageId = 1进行过滤,但我不确定。行可以具有从1到3的LanguageId,也可以仅具有ID 2等。行肯定会至少有一个LanguageId。

现在我的问题是:如何连接具有唯一值的表,忽略一个完全不相关的列?

0
0 Comments

问题出现的原因是在SQL语句中使用了LEFT JOIN关键字,但是需要获取的结果只是LEFT JOIN连接中的第一行数据。解决方法有两种:一种是将查询的结果再套一层查询,另一种是在查询中不提取需要的列。

第一种方法的SQL语句如下:

SELECT RequiredId, <all_the_other_fields> from (
SELECT t2.SomeId AS RequiredId
-- ...other data mainly from t2
FROM DataTable1 AS t1
   LEFT JOIN DataTable2 AS t2 
   ON t2.OtherId = t1.ExperienceId 
   AND t2.LanguageId = 
      (SELECT TOP 1 t1.LanguageId
      ORDER BY t1.LanguageId)
   ) group by RequiredId, <all_the_other_fields> 

第二种方法的SQL语句如下:

SELECT distinct t2.SomeId AS RequiredId
-- ...other data mainly from t2 BUT not the Language id
FROM DataTable1 AS t1
   LEFT JOIN DataTable2 AS t2 
   ON t2.OtherId = t1.ExperienceId 
   AND t2.LanguageId = 
      (SELECT TOP 1 t1.LanguageId
      ORDER BY t1.LanguageId)

感谢回答者的第一种方法,它解决了我的问题。之前在使用EF时遇到了问题,直到我看到我的GROUP BY子句在内部查询中而不是外部查询中。我改变了这一点,现在它可以正常工作了。

0
0 Comments

在这段代码中,出现了一个问题:需要使用 LEFT JOIN 来获取 DataTable1DataTable2 的关联数据,但是只需要 DataTable2 中的第一行数据。

问题的原因是,使用 LEFT JOIN 时,会返回所有匹配条件的数据行。但是在实际需求中,只需要获取 DataTable2 中和 DataTable1 匹配的第一行数据。

解决这个问题的方法是,使用 OUTER APPLY 子查询,并在子查询中使用 TOP 1ORDER BY 来限制结果集只返回第一行数据。这样就可以达到只获取第一行数据的目的。

下面是修改后的代码示例:

SELECT 
    t1.SomeId AS RequiredId,
    -- ...other data mainly from t1
    t2.LanguageId
FROM DataTable1 AS t1
OUTER APPLY (
    SELECT TOP 1 
        t2.LanguageId
    FROM DataTable2 AS t2
    WHERE t2.OtherId = t1.ExperienceId
    AND t2.LanguageId = t1.LanguageId
    ORDER BY t2.LanguageId
) AS t2

0
0 Comments

问题的出现原因是在使用SQL的LEFT JOIN操作时,需要从两个表中联接数据,但只需要获取其中一个表的第一行数据。在没有特定方法的情况下,LEFT JOIN操作会返回所有匹配的行,而不仅仅是第一行。

为了解决这个问题,可以使用CTE(通用表达式)和ROW_NUMBER函数来获取每个someid分组中的第一行数据,并将其与datatable1进行LEFT JOIN操作。以下是解决方法的代码:

;with cte as 
(select *, row_number() over (partition by someid order by languageid) rn
 from datatable2)
select * 
from datatable1 dt
left join cte c on dt.experienceid = c.otherid and c.rn = 1

以上代码使用CTE创建了一个临时表cte,其中包含datatable2表的所有数据,并根据someid分组和languageid排序。ROW_NUMBER函数在每个分组中为每行分配一个唯一的行号。然后,使用LEFT JOIN操作将datatable1和cte表连接,条件是experienceid等于otherid,并且行号rn等于1,这样就只返回了datatable1中的第一行数据。

0