我正在尝试显示所有用户的上次修改日期/时间。 用户信息分布在多个表中(所有表都包含last_modified_date列)。 下表如下。 User_Details, User_Contact_Details, User_Social_Media_Details。
我的第一个想法是执行如下UNION ALL。
select user.id, user.last_modified_date from
(
(select id, last_modified_date from "User_Details" order by id)
UNION ALL
(select user_id as id, last_modified_date from "User_Contact_Details" order by id)
UNION ALL
(select user_id as id, last_modified_date from "User_Social_Media_Details" order by id)
) as user
where user.last_modified_date is not null
order by user.id, user.last_modified_date desc
这将为我提供所有用户及其上次修改日期的降序排列,然后为每个用户执行前1名。 这让我想知道这是否是正确且优化的方法。
非常感谢您的帮助/建议。
答案 0 :(得分:1)
如果我正确理解了这个问题,那么您希望每个用户的最新修改日期。归结为一个greatest-n-per-group问题(n = 1)。通常在Postgres中使用distinct on ()
可以解决这些问题:
select distinct on (usr.id) id, last_modified_date
from
(
select id, last_modified_date
from "User_Details"
UNION ALL
select user_id as id, last_modified_date
from "User_Contact_Details"
UNION ALL
select user_id as id, last_modified_date
from "User_Social_Media_Details"
) as usr
where last_modified_date is not null
order by id, last_modified_date desc;
并集查询中的order by
并不是真正必要的,除非您已经想要在其中预先过滤用户ID,这可能会更有效:
select distinct on (usr.id) id, last_modified_date
from
(
select distinct on (id) id, last_modified_date
from "User_Details"
order by id, last_modified_date desc
UNION ALL
select distinct on (user_id) user_id as id, last_modified_date
from "User_Contact_Details"
order by user_id, last_modified_date desc
UNION ALL
select distinct on (user_id) user_id as id, last_modified_date
from "User_Social_Media_Details"
order by user_id, last_modified_date desc
) as usr
where last_modified_date is not null
order by id, last_modified_date desc;
您仍然需要在外部查询中使用distinct on ()
,因为可以从UNION的不同分支返回相同的用户ID。
user
是保留关键字,请避免将其用作标识符。而且,如果这样做,则必须引用它"user"
以避免与内置函数user
如果"User_Details"
表是其他人引用的“主”表,并且您只想获取每个用户ID的最新修改日期,无论发生在哪个表中,也可以使用分组依据:
select id,
max(greatest(ud.last_modified_date, ucd.last_modified_date, usmd.last_modified_date)) as latest_modification
from "User_Details" ud
left join "User_Contact_Details" ucd on ucd.user_ud = ud.id
left join "User_Social_Media_Details" usmd on usmd.user_id = ud.id
group by id;
答案 1 :(得分:0)
在每个表上独立运行:
select u.id, u.last_modified_date
from ((select id, last_modified_date
from "User_Details"
order by last_modified_date desc
limit 1
) union all
(select user_id, last_modified_date
from "User_Contact_Details"
order by last_modified_date desc
limit 1
) union all
(select user_id, last_modified_date
from "User_Media_Details"
order by last_modified_date desc
limit 1
)
) u
order by last_modified_date desc
limit 1;
通过在子查询中运行limit
,数据库引擎仅返回一行并可以使用索引。
编辑:
如果您需要 each 个用户而不是全部用户使用,则在子查询和外部查询中使用group by
:
select u.id, max(u.last_modified_date)
from ((select id, max(last_modified_date) as last_modified_date
from "User_Details"
group by id
) union all
(select user_id, max(last_modified_date) as last_modified_date
from "User_Contact_Details"
group by user_id
) union all
(select user_id, max(last_modified_date) as last_modified_date
from "User_Media_Details"
group by user_id
)
) u
group by user_id;