Sql mns然后你会有你的单身科学家和更新。如果您非常希望将它们作为JSON,那么假设这真的是postgres,那么您必须使用将给出单个JSON值的_JSON和row _to _JSON,但这并不会增加很多单个列尚未提供的内容。Postgres如果这是Postgres,它将允许您按*分组,以便json工作: SELECT p.column, row_to_json(s), row_to_json(u), count(*) ... GROUP BY p.column, s.*, u.*

Sql mns然后你会有你的单身科学家和更新。如果您非常希望将它们作为JSON,那么假设这真的是postgres,那么您必须使用将给出单个JSON值的_JSON和row _to _JSON,但这并不会增加很多单个列尚未提供的内容。Postgres如果这是Postgres,它将允许您按*分组,以便json工作: SELECT p.column, row_to_json(s), row_to_json(u), count(*) ... GROUP BY p.column, s.*, u.*,sql,json,postgresql,count,left-join,Sql,Json,Postgresql,Count,Left Join,s.*和u.*的存在将允许row_to_json调用生成描述s和u的单行json,如果您有以下情况,则计数将对Cs进行计数: SELECT p.column, s.column, u.column FROM p JOIN s ON ... JOIN u ON ... 它产生一行 p1, s1, u1 然后将另一个表加入: SELECT p.column, s.column, u.column, c.column FROM p JOIN s ON ... JOI

s.*和u.*的存在将允许row_to_json调用生成描述s和u的单行json,如果您有以下情况,则计数将对Cs进行计数:

SELECT p.column, s.column, u.column
FROM 
  p 
  JOIN s ON ...
  JOIN u ON ...
它产生一行

p1, s1, u1
然后将另一个表加入:

SELECT p.column, s.column, u.column, c.column
FROM 
  p 
  JOIN s ON ...
  JOIN u ON ...
  JOIN c ON ...
它突然产生了5行

p1, s1, u1, c1
p1, s1, u1, c2
p1, s1, u1, c3
p1, s1, u1, c4
p1, s1, u1, c5   
您希望它再次生成一行,但另一列的计数为5:

p1, s1, u1, 5
然后需要对重复数据进行分组并添加计数:

SELECT p.column, s.column, u.column, count(*)
FROM 
  p 
  JOIN s ON ...
  JOIN u ON ...
  JOIN c ON ...
GROUP BY p.column, s.column, u.column
您将注意到,GROUPBY section只不过是SELECT section的精确重复,减去了聚合列的计数

数据库将根据group BY中指定的键对数据进行分组。p1、s1、u1是一个独特的组合,与5个不同的c1相关联。。c5值。本例中的聚合不适用于cX数据,因为它是count*,但它可以-如果我们说:

SELECT p.column, s.column, u.column, min(c.column), max(c.column)
然后DB将该数据集与包含所有c值的bucket一起设置:

p1, s1, u1, [c1, c2, c3, c4, c5]
并将MIN和MAX函数分别应用于[c1、c2、c3、c4、c5]铲斗牵引c1和c5

在您看来,习惯于将分组操作视为准备group by中列的唯一组合,再加上将所有这些其他数据项放在一个无序的大存储桶中,MAX/MIN/AVG etc函数对存储桶内容进行操作,并提取可能来自任何行的相关数据,当然,MIN和MAX可能来自不同的行。分组会丢失此输入行的概念,因为它准备了一组新的行

在各种数据库中最典型的分组情况下,如果正在分组,则不能使用SELECT*——列出SELECT中的每一列,然后再列出GROUP BY中的每一列。这似乎是多余的,事实上,某些数据库允许您跳过提供分组方式,但在高级场景中,可以根据您选择的不同内容进行分组,因此仅在简单情况下是多余的

现在,希望你能接受以上的一切。有些数据库的函数不仅仅是MIN/MAX等,还将连接bucket中的所有结果。类似于以下伪SQL:

SELECT p.column, s.column, u.column, STRING_JOIN(c.column, '|')
可以产生:

p1, s1, u1, c1|c2|c3|c4|c5
string_join函数被设计为使用指定为分隔符的管道字符将bucket中的所有内容连接在一起

但请记住,我们的原始数据是:

p1, s1, u1, c1
p1, s1, u1, c2
p1, s1, u1, c3
p1, s1, u1, c4
p1, s1, u1, c5  
p1, x1, y1
p1, x2, y2
如果我们只按p.column分组,DB会将p1作为键和更多的bucket:

p1, [s1,s1,s1,s1,s1], [u1,u1,u1,u1,u1], [c1,c2,c3,c4,c5]
如果你把每一个都串起来,你最终会得到你想要的:

SELECT p.column, STRING_JOIN(s.column, '|'), STRING_JOIN(u.column, '|'), STRING_JOIN(c.column, '|'), 

p1, s1|s1|s1|s1|s1, u1|u1|u1|u1|u1, c1|c2|c3|c4|c5
DB中没有任何AI会在加入之前查看并说我将从s和u存储桶中删除重复项,也不应该这样做。正如我前面提到的,当数据进入bucket进行聚合时,所有行和顺序的概念都会丢失。如果您的数据是:

p1, s1, u1, c1
p1, s1, u1, c2
p1, s1, u1, c3
p1, s1, u1, c4
p1, s1, u1, c5  
p1, x1, y1
p1, x2, y2
而你的分组/加入最终可能会导致

p1, x1|x2, y2|y1
请参见Y字符串中元素的顺序与x相反-不要依赖集合中元素的顺序来推断任何有关元素的信息,例如它们最初来自的行

那么,你的问题是怎么回事?好的,您只通过一个列进行分组,并聚合其他列,如上所述,这样您就可以看到如何获得未分组列的重复

如果你继续按所有列分组,那么你就会有你的单个科学家和更新。如果您非常希望将它们作为JSON,那么假设这真的是postgres,那么您必须使用将给出单个JSON值的_JSON和row _to _JSON,但这并不会增加很多单个列尚未提供的内容。Postgres如果这是Postgres,它将允许您按*分组,以便json工作:

SELECT p.column, row_to_json(s), row_to_json(u), count(*)
...
GROUP BY p.column, s.*, u.*

s.*和u.*的存在将允许row_to_json调用生成描述s和u的一行json,并且计数将对多行的Cs

进行计数,因为多个表中有多个匹配项,正如Caius Jard所彻底解释的那样

典型的解决方案是在子查询中预聚合。对于仅在项目上进行过滤的用例,横向联接应该是最有效的选项:

SELECT p.*, u.*, s.*, c.*
FROM projects
CROSS JOIN LATERAL (
    SELECT coalesce(json_agg(updates ORDER BY update_date DESC) FILTER (WHERE u.id IS NOT NULL), '[]') AS updates
    FROM updates u
    WHERE u.project_id = p.id
) u
CROSS JOIN LATERAL (
    SELECT coalesce(json_agg(scientists) FILTER (WHERE s.user_id IS NOT NULL), '[]') AS scientists
    FROM scientists s
    WHERE s.project_id = p.id
) s
CROSS JOIN LATERAL (
    SELECT coalesce(SUM(c.amount), 0) AS donated, coalesce(COUNT(charges), 0) AS num_donations
    FROM charges c
    WHERE c.project_id = p.id
) c ON TRUE
WHERE p.id = '${id}'

您的连接是多行的,因为在几个表中有多个匹配项,正如Caius Jard所彻底解释的那样

典型的解决方案是在子查询中预聚合。对于仅在项目上进行过滤的用例,横向联接应该是最有效的选项:

SELECT p.*, u.*, s.*, c.*
FROM projects
CROSS JOIN LATERAL (
    SELECT coalesce(json_agg(updates ORDER BY update_date DESC) FILTER (WHERE u.id IS NOT NULL), '[]') AS updates
    FROM updates u
    WHERE u.project_id = p.id
) u
CROSS JOIN LATERAL (
    SELECT coalesce(json_agg(scientists) FILTER (WHERE s.user_id IS NOT NULL), '[]') AS scientists
    FROM scientists s
    WHERE s.project_id = p.id
) s
CROSS JOIN LATERAL (
    SELECT coalesce(SUM(c.amount), 0) AS donated, coalesce(COUNT(charges), 0) AS num_donations
    FROM charges c
    WHERE c.project_id = p.id
) c ON TRUE
WHERE p.id = '${id}'
基本问题与此处完全相同:

你后来评论说:

数据库中只有一个与该项目id关联的不同的更新和更新

如果这保证是真的,你 需要在加入之前聚合表费用中的行:

选择p* ,合并到_jsonu,“[]”作为更新 ,作为科学家的联合体,“[]” ,c ,c.num_ 来自项目p 左连接在u.project_id=p.id上更新u 在s.project_id=p.id上左键连接s 交叉连接 选择合并金额,0作为捐赠 ,将*计算为捐赠数量 控告 其中project_id='${id}' C 其中p.id='${id}' 收费子查询可以如此简单,因为唯一的筛选器与外部查询中使用的ID相同。我们也不需要为计数合并,因为

... count无论如何都不会返回NULL。见: ... 具有聚合函数且没有GROUP BY的子查询保证只返回一行,聚合所有符合条件的行-即使0行符合条件。 如果表中可能有多个相关行,请在交叉连接之前以类似的方式进行聚合。

基本问题与此处完全相同:

你后来评论说:

数据库中只有一个与该项目id关联的不同的更新和更新

如果保证为真,则只需在加入之前聚合表费用中的行:

选择p* ,合并到_jsonu,“[]”作为更新 ,作为科学家的联合体,“[]” ,c ,c.num_ 来自项目p 左连接在u.project_id=p.id上更新u 在s.project_id=p.id上左键连接s 交叉连接 选择合并金额,0作为捐赠 ,将*计算为捐赠数量 控告 其中project_id='${id}' C 其中p.id='${id}' 收费子查询可以如此简单,因为唯一的筛选器与外部查询中使用的ID相同。我们也不需要为计数合并,因为

... count无论如何都不会返回NULL。见: ... 具有聚合函数且没有GROUP BY的子查询保证只返回一行,聚合所有符合条件的行-即使0行符合条件。
如果表中可能有多个相关行,请在交叉连接之前以类似的方式进行聚合。

以表格格式提供示例数据和预期输出更新它!谢谢你的建议@Fahmi如果有5项费用,那么每个科学家都会被退回5次-所以只限制你想要的1项费用。这称为笛卡尔积。db会满足你的要求;你必须更准确地提出你的要求。你没有告诉我们你想要哪一项收费最新、最高,将所有收费分组到一个csv中,所以我们不知道该怎么做,就像数据库知道该怎么做一样do@CaiusJard我想我理解不对。我希望返回指定项目id的所有科学家和更新,但数据库中只有一个与该项目id关联的不同更新和科学家。当我添加带有与项目id关联的X个不同费用的连接时,科学家和更新会重复X次。当然,它们是重复的。您希望矩形结果网格的外观如何?您有1个项目、1个项目科学家、1个项目更新和5个项目费用。若你们加入项目,科学家和更新,你们将得到1行。在数据库中添加费用时,必须重复项目/科学家/更新数据5次,每5次费用重复一次。如果只有最新的费用是相关的,那么您进行该部分的查询,因为五个费用行中只有一行适用,您将再次获得一行提供样本数据,并且您的预期输出以表格格式更新它!谢谢你的建议@Fahmi如果有5项费用,那么每个科学家都会被退回5次-所以只限制你想要的1项费用。这称为笛卡尔积。db会满足你的要求;你必须更准确地提出你的要求。你没有告诉我们你想要哪一项收费最新、最高,将所有收费分组到一个csv中,所以我们不知道该怎么做,就像数据库知道该怎么做一样do@CaiusJard我想我理解不对。我希望返回指定项目id的所有科学家和更新,但数据库中只有一个与该项目id关联的不同更新和科学家。当我添加带有与项目id关联的X个不同费用的连接时,科学家和更新会重复X次。当然,它们是重复的。您希望矩形结果网格的外观如何?您有1个项目、1个项目科学家、1个项目更新和5个项目费用。若你们加入项目,科学家和更新,你们将得到1行。在数据库中添加费用时,必须重复项目/科学家/更新数据5次,每5次费用重复一次。如果只有最新的费用是相关的,那么您进行该部分的查询,因为五个费用行中只有一行适用,您将再次获得一行谢谢!我想我知道了
人们常说有一位与众不同的科学家,但事实并非如此。使用交叉连接对我有用!谢谢你!我想我说有一位与众不同的科学家,这让人们感到困惑,而事实并非如此。使用交叉连接对我有用!