gpt4 book ai didi

sql - 跨多个表查询避免联合所有

转载 作者:行者123 更新时间:2023-11-29 13:51:36 24 4
gpt4 key购买 nike

我尝试查询以下数据库表:

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_categoryd.user_id(t_documents 表) 在查询的底部。您确定您指的不是 s.user_categorys.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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com