SQL LEFT JOIN 仅第一行
Posted
技术标签:
【中文标题】SQL LEFT JOIN 仅第一行【英文标题】:SQL LEFT JOIN first row only 【发布时间】:2014-07-17 07:48:00 【问题描述】:假设我们有这样的数据集:
表: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
-- ...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)
这个查询应该返回(如果没有错,很清楚)行:
SomeId ...
----------------
459 ...
245 ...
295 ...
...
现在它返回三倍相同的数据(只有 LanguageId 不同)。
如果我确定它始终存在,我会尝试使用WHERE t1.LanguageId = 1
过滤它,但我不确定。行可以是LanguageId
,从1到3,也可以只有ID 2,等等。行肯定至少有一个LanguageId
。
现在我的问题是:如何连接具有唯一值且一列完全忽略的表?
【问题讨论】:
尝试使用group by LanguageId
【参考方案1】:
将其包装在另一个查询中是否有效?
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>
或者甚至不首先提取列?
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 子句在内部查询中,而不是在它之外。改变了它,现在它可以工作了。【参考方案2】:试试这个:
;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
【讨论】:
【参考方案3】:对于这样的事情,当你需要在子查询CROSS APPLY
OR 'OUTER APPLY
'中选择top
时非常方便
t2.SomeId AS RequiredId
-- ...other data mainly from t2
FROM DataTable1 AS t1
OUTER APPLY ( SELECT TOP 1 t1.LanguageId
FROM DataTable2
WHERE DataTable2 .OtherId = t1.ExperienceId
AND t2.LanguageId = t1.LanguageId
ORDER BY t1.LanguageId
) AS t2
【讨论】:
【参考方案4】:试试这个:
SELECT DISTINCT t2.SomeId AS RequiredId
-- ...other data mainly from t2
FROM DataTable1 AS t1
LEFT JOIN DataTable2 AS t2
ON t2.OtherId = t1.ExperienceId
WHERE t2.LanguageId = t1.LanguageId
【讨论】:
【参考方案5】:你在找这个吗(小提琴:http://sqlfiddle.com/#!3/811b8/12)?:
SELECT dt2.*
FROM DataTable1 dt1 INNER JOIN DataTable2 dt2
ON dt1.ExperienceID = dt2.OtherID AND
dt1.LanguageID = dt2.LanguageID
WHERE dt2.LanguageID = (SELECT MIN(LanguageID) FROM DataTable1);
产生:
ID SOMEID OTHERID LANGUAGEID
1 459 1 1
4 245 2 1
7 295 3 1
【讨论】:
以上是关于SQL LEFT JOIN 仅第一行的主要内容,如果未能解决你的问题,请参考以下文章
SQL - LEFT JOIN 和 WHERE 语句仅显示第一行
SQL Server:与 TOP 1 的 LEFT OUTER JOIN 最多选择一行
SQL Server 中的 LEFT JOIN 与 LEFT OUTER JOIN
SQL JOINSQL INNER JOIN 关键字SQL LEFT JOIN 关键字SQL RIGHT JOIN 关键字SQL FULL JOIN 关键字