我尝试查询以下数据库表:
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
我想找到您拥有并共享访问权限的所有文档。 IE。在 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)
);
最佳答案
这是您的查询:
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)
关于sql - 跨多个表查询避免联合所有,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40055420/