SQL LEFT JOIN仅限第一行

时间:2014-07-17 07:48:01

标签: sql sql-server 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
    -- ...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

现在我的问题是:我如何连接具有唯一值的表,其中一列完全被忽略

6 个答案:

答案 0 :(得分: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)

答案 1 :(得分:1)

对于需要在子查询top或{&#39; CROSS APPLY&#39;中选择OUTER APPLY的情况。非常方便

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

答案 2 :(得分:0)

试试这个:

;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 :(得分:0)

试试这个:

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

答案 4 :(得分:0)

你在寻找这个(小提琴: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

答案 5 :(得分:-1)

如果您使用的LanguageID类型为int,可以尝试MAXMIN功能选择

前:

SELECT MIN(LanguageID)