【问题标题】:SQL GROUP BY column from related table相关表中的 SQL GROUP BY 列
【发布时间】:2017-04-06 18:30:17
【问题描述】:

我有桌子 T1

ID     RESOLVER   RESOLVEDBY
1      A          GROUP1
2      A          GROUP1
3      A          GROUP1
4      B          GROUP1
5      B          GROUP1

我还有 T2 桌

GROUPID   GROUP      PERSON
1         GROUP1     A      
2         GROUP1     B
3         GROUP1     C

我做了这个 SQL 查询,它返回每个人解析了多少条记录

select resolver,count(*) from T1
where resolvedby='GROUP1'
group by resolver

并且返回正确

A 3
B 2

但是,我还想检索属于该组的所有人员的此统计信息,因此对于用户 C,我希望值为 0。 所以最终的结果应该是

A 3
B 2
C 0

【问题讨论】:

  • right outer join.
  • 您的结果与您的数据不匹配。你似乎加入了resolver=person
  • 抱歉,我更正并编辑了我如何返回当前结果的声明。但仍然是如何检索所需结果的问题
  • 你在两个表中都有组,因为它们构成了自然键(即一个人的名字可以出现多次,但每个组只能出现一次),对吗?
  • 是的,每组一次,但如果该人也是另一个组的成员,则可以多次显示人名

标签: sql select group-by db2


【解决方案1】:

根据您的编辑:

您需要将现有的 Select 外部连接到第二个表:

select t2.person, coalesce(cnt, 0)
from T2
left join
 ( -- aggregate before join (usually more efficient)
   select resolver,count(*) as cnt
   from T1
   where resolvedby='GROUP1'
   group by resolver
 ) as T1
on T1.resolver=T2.person
where t2."GROUP"='GROUP1' -- adding double quotes as GROUP is usually a keyword

【讨论】:

  • @Dejan:您的示例数据中也有GROUP1 数据。在您进行新的编辑后,它的列是 GROUP
  • 对不起,我看到了我的错误...我现在更正了第一个表中的列是 RESOLVEDBY,而第二个表中的列是 GROUP。您现在可以仔细检查您的查询吗?谢谢和抱歉
  • 感谢它只起作用了我需要的一件事,即您必须更改 T2.resolver=T1.person 而不是 T1.resolver=T2.person 正确吗?
  • 还有一个小问题,如果我想另外过滤 T1 表,我只需要过滤第一个 WHERE 子句是否正确?我不必在第二个 WHERE 中添加任何东西???这只是额外过滤 T1 表的问题..其他一切都保留
  • @Dejan:您可以向 T1 添加任何其他 WHERE 条件,当然这可能会更改返回的计数。
【解决方案2】:

将计数外连接到 person 表。当T2中没有条目时,使用COALESCE显示0。

select t2.person, t2.group, coalesce(counted.cnt, 0)
from t2
left join
(
  select resolver, resolvedby, count(*) as cnt
  from T1
  group by resolver, resolvedby
) counted on counted.resolver = t2.person and counted.resolvedby = t2.group
where t2.group = 'GROUP1';

您也可以在 select 子句中使用子查询:

select 
  t2.person, 
  t2.group, 
  (select count(*) from t1 where t1.resolver = t2.person and t1.resolvedby = t2.group)
from t2
where t2.group = 'GROUP1';

【讨论】:

  • 谢谢,只是一个小问题,如果我想另外过滤 T1 表,我需要过滤只是为了将 WHERE 放在第一个 where 子句中正确吗?或者我将不得不在第二个 WHERE 中添加额外的条件???这只是额外过滤 T1 表的问题..其他一切都保留
  • 如果你想过滤 T1 记录(例如,只计算那些在记录中设置了标志的记录)将条件放在 T1 的 where 子句中,即在 where 紧跟在 from t1 之后。跨度>
  • 嗨,Thorsten,你能帮我解决这个问题吗? stackoverflow.com/questions/43364018/… 谢谢
【解决方案3】:

您需要一个外连接来从 T2 返回所有记录。下面的查询使用 RIGHT OUTER JOIN 返回 T2 中的所有行(即包括 C 行)并获取每个行的匹配计数:

select T2.PERSON, count(T1.ID) from T1
right outer join T2 on T2.PERSON=T1.RESOLVER 
where T2.group ='GROUP1' -- If this was T1.group, we'd have to use COALESCE() to prevent dropping out rows in T2 that don't have a resolution in T1 
group by T2.PERSON

在上面,我们使用右外连接,因为我们需要从表/表达式到语句right outer join 的所有行。如果我们先用T2 编写查询的FROM 子句,它就会是这样的左外连接:...T2 left outer join T1...

【讨论】:

  • 请看一下我使用的修改后的sql。不幸的是,您的查询没有给我我想要的。你能注意到错误吗?
  • @Dejan - 我用WHERE 子句更新了我的答案中的查询。请注意,您的示例中的列名不匹配 :-) 例如,您的查询有 where resolvedby='GROUP1' 但在 T1 或 T2 中没有 resolvedby 列。
  • 对不起,我看到了我的错误...我现在更正了第一个表中的列是 RESOLVEDBY,而第二个表中的列是 GROUP。您现在可以仔细检查您的查询吗?谢谢和抱歉
【解决方案4】:

使用以下查询根据您的要求获得预期的输出。

select person,count(resolver) from t2 left join t1 on t2.groups=t1.groups and t2.person = t1.resolver  group by person;

OUTPUT : 

mysql> select person,count(resolver) from t2 left join t1 on t2.person = t1.resolver  group by person;
+--------+-----------------+
| person | count(resolver) |
+--------+-----------------+
| A      |               4 |
| B      |               3 |
| C      |               0 |
+--------+-----------------+
3 rows in set (0.01 sec)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-21
    • 2014-08-29
    • 1970-01-01
    • 2011-10-13
    • 1970-01-01
    • 2017-01-03
    相关资源
    最近更新 更多