我有两张桌子:
User (id, name)
UserEvent (id, user_id, name, date)
如何让最后一个(按日期排序)UserEvent.name
的值为''?
我在SQLFiddle上写了一个示例,其中包含一些特定的数据:http://sqlfiddle.com/#!9/b76e24 - 对于这种情况,我只会得到' Mery'来自表User
,因为即使约翰'已关联的事件名称最后一个未被播放'。
答案 0 :(得分:1)
这可能是最快的:
SELECT u.*
FROM usr u -- avoiding "User" as table name
JOIN LATERAL (
SELECT name
FROM userevent
WHERE user_id = u.id
ORDER BY date DESC NULLS LAST
LIMIT 1
) ue ON ue.name = 'played';
LATERAL
需要Postgres 9.3 + :
或者你可以使用DISTINCT ON
(每个用户几行更快):
SELECT u.*
FROM usr u -- avoiding "User" as table name
JOIN (
SELECT DISTINCT ON (user_id)
user_id, name
FROM userevent
ORDER BY user_id, date DESC NULLS LAST
) ue ON ue.user_id = u.id
AND ue.name = 'played';
DISTINCT ON
的详细信息:
如果定义date
NOT NULL
,则不需要NULLS LAST
。 (在下面的索引中都没有。)
读取两者的效果的关键,尤其是第一个查询是匹配的多列索引:
CREATE INDEX userevent_foo_idx ON userevent (user_id, date DESC NULLS LAST, name);
除此之外:切勿使用reserved words作为标识符。
答案 1 :(得分:0)
按用户ID返回用户事件分组的最大日期。获取结果集并通过用户ID和最大日期将其连接回用户事件,并仅过滤播放的记录。
答案 2 :(得分:0)
这是:
首先,我从每个用户处获取MAX ID并使用此ID将其加入ROW 为了测试状态是否“播放”,如果是,我得到他们的用户名。
SELECT
ids.*,
u.name,
ue.*
FROM (
SELECt max(id) AS id from UserEvent
GROUP by user_id
) as ids
LEFT JOIN UserEvent ue ON ue.id = ids.id
LEFT JOIN User u ON u.id = ue.user_id
WHERE ue.name = 'played';