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中运行此查询?如果是这样的话,我会在那里检查它,而不是在查询本身中,但是using
case
也会进行检查,是的,这是JS后来抛出的错误。想用那个案例更新你的答案吗?我希望得到空数组而不是[null]。谢谢@实际上,使用
coalesce
case
更干净-参见我编辑的answer@VidličkaLujVitón捕得好!我错过了
array\u agg
如何处理
null
s。我已将其编辑到我的答案中,以便将来有人查找时更有用。我发现
无法将未定义或null转换为object
,因为我猜,
行到JSON
无法找到类别。我需要现在就选择这个案例,不是吗?@VidličkaLujVitón,这看起来不像PostgeSQL错误。您是否正在Node.js中运行此查询?如果是这样的话,我会在那里检查它,而不是在查询本身中,但是using
case
也会进行检查,是的,这是JS后来抛出的错误。想用那个案例更新你的答案吗?我希望得到空数组而不是[null]。谢谢@实际上,使用
coalesce
case
更干净-参见我编辑的answer@VidličkaLujVitón捕得好!我错过了
array\u agg
如何处理
null
s。我已将此编辑到我的答案中,以便将来有人查找时更有用。