连接到具有多行的表,用于连接项

时间:2009-07-09 14:55:47

标签: sql sql-server tsql

我有一个表users,其中包含主键userid和日期时间列pay_date

我还有一个表user_actions,通过列users引用userid,以及日期时间列action_date

我希望将这两个表连接在一起,只从user_actions表中获取最早的action_date晚于或等于pay_date的操作。

我正在尝试这样的事情:

select users.userid from users
left join user_actions on user_actions.userid = users.userid
where user_actions.action_date >= users.pay_date
order by user_actions.pay_date

但很明显,每个用户返回多行(一个用于pay_date之后或之后发生的每个用户操作)。不知道从哪里开始?

对于看似简单的问题的道歉,我对t-sql相当新。

3 个答案:

答案 0 :(得分:5)

CROSS APPLY是你的朋友:

select users.*, t.* from users
CROSS APPLY(SELECT TOP 1 * FROM user_actions WHERE user_actions.userid = users.userid
AND user_actions.action_date >= users.pay_date
order by user_actions.pay_date) AS t

答案 1 :(得分:4)

如果PRIMARY KEY上有user_actions

SELECT  u.*, ua.*
FROM    users u
LEFT JOIN
        user_actions ua
ON      user_actions.id = 
        (
        SELECT  TOP 1 id
        FROM    user_actions uai
        WHERE   uai.userid = u.userid
                AND uai.action_date >= u.pay_date
        ORDER BY
                uai.action_date
        )

如果你不这样做:

WITH    j AS
        (
        SELECT  u.*, ua.*, ROW_NUMBER() OVER (PARTITION BY ua.userid ORDER BY ua.action_date) AS rn, ua.action_date
        FROM    users u
        LEFT JOIN
                user_actions ua
        ON      ua.userid = u.userid
                AND ua.action_date >= u.pay_date
        )
SELECT  *
FROM    j
WHERE   rn = 1 or action_date is null

<强>更新

CROSS APPLY提出的

@AlexKuznetsov更优雅高效。

答案 2 :(得分:0)

select u.*, ua.* from
    users u join users_actions ua on u.userid = ua.userid
where
    ua.action_date in
            (select min(action_date) from user_actions ua1
             where
                  ua1.action_date >= u.pay_date and
                  u.userid=ua1.userid)