SQL条件字段,首先匹配JOIN

时间:2017-10-19 12:48:52

标签: sql sql-server

假设我有两张桌子:

user
--userid
--fname
--lname

widget
--id
--userid
--value

user.userid = widget.userid

如果有{1}}的用户,如果他们有一个, AND(!),如果有超过1个小部件,我希望看到第一个匹配的用户的完整列表。没有widget = null字段

Widget.value

我不能做简单的连接,如果没有' widget.value'对于某些用户来说用户不会被显示

id fname lname value 1 John Doe X8 也不起作用

我需要

  • 1 widget = value
  •   

    2个小部件=第一个

  • 0 widgets = null field

4 个答案:

答案 0 :(得分:1)

使用top with ties

select top 1 with ties
  u.*, w.id, w.value
from dbo.user u
  left join dbo.widget w 
    on u.userid = w.userid
order by row_number() over (partition by u.userid order by w.id);

<小时/> 将common table expressionrow_number()

一起使用
;with cte as (
    select u.*, w.id, w.value
      , rn = row_number() over (partition by u.userid order by w.id)
    from dbo.user u
      left join dbo.widget w 
        on u.userid = w.userid
)
select *
from cte
where rn = 1;

答案 1 :(得分:0)

outer apply应该做你想做的事:

select u.*, w.value
from user u outer apply
     (select top 1 w.*
      from widgets w
      where w.userid = u.userid
      order by id  -- or however you define the first one
     ) w;

答案 2 :(得分:0)

试试这个:

SELECT
  u.userid, u.fname, u.lname, w.value
FROM user as u
LEFT JOIN
(
   SELECT w1.*
   FROM widget as w1
   INNER JOIN
   (
      SELECT userid, MAX(id) AS LatestId
      FROM widget
      GROUP BY userid
   ) AS w2 ON w1.userid = w2.userid and w1.id = w2.latestid
) AS w ON u.userid = w.userid;
  • 带有max和group by的子查询的内部联接将为每个用户ID提供最新的行(如果有)。所以对于那些超过1行的人,你会得到最新的一行。
  • 没有日期,所以我认为最大ID是最新的,可能并非总是如此。
  • LEFT JOIN将在窗口小部件表中包含具有不匹配行的行,因此如果没有窗口小部件的用户,您将获得值null

答案 3 :(得分:0)

SELECT u.userid, w.value
FROM user u
OUTER APPLY (
    SELECT TOP 1 w.value
    FROM widget w
    WHERE w.userid = u.userid
    ORDER BY w.id --order by whatever makes a widget the first one
) w