我正在尝试查询以下数据库表:
t_shared_users
user_id
user_category
folder_id
expiry
t_documents
id
folder_id
user_id
user_category
description
created
updated
t_folder
id
type
user_id
user_category
created
updated
我想找到您拥有并拥有共享访问权限的所有文档。即。搜索t_documents中user_id = 1 AND user_category = 100的所有文档,但也包括您在t_shared_users中可以访问的文件夹中的那些文档。以下是我对查询的尝试:
SELECT
id,
folder_id,
user_id,
user_category,
description,
created,
updated
FROM
t_documents
WHERE
user_category = 100
AND user_id = 1
UNION ALL
SELECT
d.id,
d.folder_id,
d.user_id,
d.user_category,
d.description,
d.created,
d.updated
FROM
t_documents d
JOIN
t_shared_users s
ON
d.folder_id = s.folder_id
WHERE
d.user_category = 100
d.AND user_id = 1
ORDER BY
created ASC
LIMIT
10
是否有更好/更高效/简洁的方式来编写此查询?以上似乎有点冗长和缓慢。
编辑:
CREATE TABLE t_folder (
id SERIAL NOT NULL,
user_category SMALLINT NOT NULL,
user_id INTEGER NOT NULL,
type INTEGER NOT NULL,
description TEXT,
created TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
updated TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
PRIMARY KEY (id)
);
CREATE TABLE t_documents (
id BIGSERIAL NOT NULL,
folder_id INTEGER,
user_category SMALLINT NOT NULL,
user_id INTEGER NOT NULL,
description TEXT NOT NULL,
created TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
updated TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
PRIMARY KEY (id)
);
CREATE TABLE t_shared_users (
id SERIAL,
folder_id INTEGER NOT NULL,
user_category INTEGER NOT NULL,
user_id INTEGER NOT NULL,
expiry TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(),
PRIMARY KEY (id)
);
答案 0 :(得分:1)
这是您的查询:
SELECT
id,
folder_id,
user_id,
user_category,
description,
created,
updated
FROM
t_documents
WHERE
user_category = 100
AND user_id = 1
UNION ALL
SELECT
d.id,
d.folder_id,
d.user_id,
d.user_category,
d.description,
d.created,
d.updated
FROM
t_documents d
JOIN
t_shared_users s
ON
d.folder_id = s.folder_id
WHERE
d.user_category = 100
AND d.user_id = 1 -- your query actually has a typo here
我对上述查询不了解的原因是您在查询底部对d.user_category
和d.user_id
(t_documents
表)进行过滤。您确定不是s.user_category
和s.user_id
(t_shared_users
)吗?如果没有,加入t_shared_users
有什么意义?
假设我的查询出错是正确的,这就是我重写它的方法:
select d.*
from t_documents d
where d.user_category = 100
and d.user_id = 1
union
select d.*
from t_shared_users s
join t_documents d
on d.folder_id = s.folder_id
where s.user_category = 100
and s.user_id = 1
请注意,我使用的是union
而不是union all
,因为我相信在技术上可能会获得可能不需要的重复文档。
另外,正如粗略的近似,这些是我为良好性能定义的索引:
t_documents (user_id, user_category)
t_documents (folder_id)
t_shared_users (user_id, user_category, folder_id)
答案 1 :(得分:-1)
从您提供的查询开始,我会将join
替换为left join
select
d.id,
d.folder_id,
d.user_id,
d.user_category,
d.description,
d.created,
d.updated
from t_documents d
left join t_shared_users s on d.folder_id = s.folder_id
where (d.user_category = 100 and d.user_id = 1)
or (s.user_category = 100 and s.user_id = 1)
这将为您提供来自t_documents
的所有条目,其中user_id = 1和user_category = 100,以及所有具有相同where子句的条目,您可以访问共享文档。