[英]Postgresql left join issue
I have two tables我有两张桌子
create table sources (
user_id bigint,
source varchar,
created timestamp default now(),
unique(user_id, source)
)
create table subscriptions (
user_id bigint unique primary key,
plan int not null references plans(id),
starts timestamp default now(),
ends timestamp default now() + interval '30' day
)
I try to select everything from sources when user has active subscription, I use this query当用户有活动订阅时,我尝试从源中选择所有内容,我使用此查询
SELECT src.* FROM sources AS src LEFT JOIN subscriptions as sub ON sub.user_id=src.user_id WHERE now() < sub.ends
However, it does not return all data, the problem became clear when I tried但是,它并没有返回所有数据,当我尝试时问题变得清晰
SELECT * FROM sources AS src LEFT JOIN subscriptions as sub ON sub.user_id=src.user_id
What may be the problem and how itspossible for me to get this info in the other way?可能是什么问题以及我如何以其他方式获取此信息? PS subscriptions table has rows with other user_id's. PS 订阅表包含其他 user_id 的行。 Thank you very much!非常感谢!
UPDATE更新
Your left join
is working.您的left join
正在工作。 If your image is of SELECT * FROM sources AS src LEFT JOIN subscriptions as sub ON sub.user_id=src.user_id
then some of your users have no subscriptions.如果您的图像是SELECT * FROM sources AS src LEFT JOIN subscriptions as sub ON sub.user_id=src.user_id
那么您的一些用户没有订阅。
SELECT * FROM sources AS src LEFT JOIN subscriptions ...
only ensures every matching row in sources
will be fetched regardless of whether it has a matching row in subscriptions
. SELECT * FROM sources AS src LEFT JOIN subscriptions ...
只确保sources
每个匹配行都将被获取,而不管它在subscriptions
中是否有匹配的行。
[I wrote the rest when I thought it was a different problem, but the advice remains.] [当我认为这是一个不同的问题时,我写了其余的,但建议仍然存在。]
This is possible because sources.user_id
is not set up as a foreign key so the database cannot enforce referential integrity .这是可能的,因为sources.user_id
未设置为外键,因此数据库无法强制执行参照完整性。 As far as the database is concerned, sources.user_id
is just some number.就数据库而言, sources.user_id
只是一些数字。 If you delete a user, their sources and subscriptions will hang around.如果您删除一个用户,他们的来源和订阅将继续存在。
In general...一般来说...
id bigserial primary key
and be done with it.提供比简单的连接表id bigserial primary key
更复杂的所有内容并完成它。not null
unless you have a good reason it should be null.除非您有充分的理由将其声明为not null
否则将所有内容声明not null
null。on delete cascade
to clean up when a user is deleted, but see below. on delete cascade
上使用以在用户被删除时进行清理,但请参见下文。create table sources (
id bigserial primary key,
-- When a user is deleted, its sources will also be deleted
user_id bigint not null references users(id) on delete cascade,
source varchar not null,
created timestamp not null default now(),
unique(user_id, source)
)
create table subscriptions (
id bigserial primary key,
-- When a user is deleted, its subscriptions will also be deleted
user_id bigint not null unique references foreign key users(id) on delete cascade,
-- Make foreign key names consistent, and use a consistent type for ids.
plan_id bigint not null references plans(id) on delete cascade,
starts timestamp not null default now(),
ends timestamp not null default now() + interval '30' day
)
Whether to use on delete cascade
when a deleted user still has sources and subscriptions depends on how you want to handle that situation.当被删除的用户仍然拥有源和订阅时,是否使用on delete cascade
取决于您希望如何处理这种情况。 You might want to prevent deleting a user which still has active sources and subs, in which case leave off on delete cascade
and handle cleaning up the user's sources and subs manually.您可能希望阻止删除仍具有活动源和子项的用户,在这种情况下,请停止on delete cascade
并手动清理用户的源和子项。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.