Sql 仅当关系数据存在时连接
这些是我的桌子Sql 仅当关系数据存在时连接,sql,postgresql,join,select,Sql,Postgresql,Join,Select,这些是我的桌子 CREATE TABLE IF NOT EXISTS categories ( category_id serial primary key, category text not null, user_id int not null ); CREATE TABLE IF NOT EXISTS activities ( activity_id serial primary key, activity text not null, user_id int n
CREATE TABLE IF NOT EXISTS categories (
category_id serial primary key,
category text not null,
user_id int not null
);
CREATE TABLE IF NOT EXISTS activities (
activity_id serial primary key,
activity text not null,
user_id int not null
);
CREATE TABLE IF NOT EXISTS categories_to_activities (
category_id int not null REFERENCES categories (category_id) ON UPDATE CASCADE ON DELETE CASCADE,
activity_id int not null REFERENCES activities (activity_id) ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT category_activity_pkey PRIMARY KEY (category_id, activity_id)
);
这是我用来获取所有活动及其类别的查询
SELECT a.*, ARRAY_AGG ( ROW_TO_JSON (c) ) categories
FROM activities a
JOIN categories_to_activities ca ON a.activity_id = ca.activity_id
JOIN categories c ON ca.category_id = c.category_id
WHERE a.user_id = ${userId}
GROUP BY a.activity_id
问题是,如果一个活动没有指定类别,它将不会被返回
我在将JOIN
与CASE
组合时遇到问题,我想这正是我所需要的。本质上,我只想在类别到活动中有一些记录时加入
如何执行此操作?您可以使用左联接
,并为没有类别的活动返回null
s:
选择一个*,
如果ca.activity_id不为NULL,则为ARRAY_AGG(ROW_TO_JSON(c))
ELSE数组[]::JSON[]
以类别结束
来自活动a
在a.activity\u id=ca.activity\u id上左连接类别\u到\u活动ca
左连接ca.category\u id=c.category\u id上的类别c
其中a.user_id=${userId}
按a.activity\u id分组
您可以使用左联接
,对于没有类别的活动返回null
s:
选择一个*,
如果ca.activity_id不为NULL,则为ARRAY_AGG(ROW_TO_JSON(c))
ELSE数组[]::JSON[]
以类别结束
来自活动a
在a.activity\u id=ca.activity\u id上左连接类别\u到\u活动ca
左连接ca.category\u id=c.category\u id上的类别c
其中a.user_id=${userId}
按a.activity\u id分组
多亏了@Murenik,我最终得到了什么
SELECT a.*,
CASE WHEN ca.activity_id IS NOT NULL
THEN ARRAY_AGG ( ROW_TO_JSON (c) )
ELSE ARRAY[]::JSON[]
END as categories
FROM activities a
LEFT JOIN categories_to_activities ca ON a.activity_id = ca.activity_id
LEFT JOIN categories c ON ca.category_id = c.category_id
WHERE a.user_id = ${userId}
GROUP BY a.activity_id, ca.activity_id
感谢@Murenik,我最终得到了什么
SELECT a.*,
CASE WHEN ca.activity_id IS NOT NULL
THEN ARRAY_AGG ( ROW_TO_JSON (c) )
ELSE ARRAY[]::JSON[]
END as categories
FROM activities a
LEFT JOIN categories_to_activities ca ON a.activity_id = ca.activity_id
LEFT JOIN categories c ON ca.category_id = c.category_id
WHERE a.user_id = ${userId}
GROUP BY a.activity_id, ca.activity_id
我得到无法将未定义或null转换为object
,因为我猜,行到JSON
无法找到类别。我需要现在就选择这个案例,不是吗?@VidličkaLujVitón,这看起来不像PostgeSQL错误。您是否正在Node.js中运行此查询?如果是这样的话,我会在那里检查它,而不是在查询本身中,但是usingcase
也会进行检查,是的,这是JS后来抛出的错误。想用那个案例更新你的答案吗?我希望得到空数组而不是[null]。谢谢@实际上,使用coalesce
比case
更干净-参见我编辑的answer@VidličkaLujVitón捕得好!我错过了array\u agg
如何处理null
s。我已将其编辑到我的答案中,以便将来有人查找时更有用。我发现无法将未定义或null转换为object
,因为我猜,行到JSON
无法找到类别。我需要现在就选择这个案例,不是吗?@VidličkaLujVitón,这看起来不像PostgeSQL错误。您是否正在Node.js中运行此查询?如果是这样的话,我会在那里检查它,而不是在查询本身中,但是usingcase
也会进行检查,是的,这是JS后来抛出的错误。想用那个案例更新你的答案吗?我希望得到空数组而不是[null]。谢谢@实际上,使用coalesce
比case
更干净-参见我编辑的answer@VidličkaLujVitón捕得好!我错过了array\u agg
如何处理null
s。我已将此编辑到我的答案中,以便将来有人查找时更有用。