首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >SQL在我的查询中添加一个有计数(*)的列

SQL在我的查询中添加一个有计数(*)的列
EN

Stack Overflow用户
提问于 2021-04-14 12:56:53
回答 3查看 78关注 0票数 0

我需要添加一个列,其中包含这个查询的内容:

代码语言:javascript
运行
复制
SELECT COUNT(*) FROM account_subscriptiongroups WHERE account_subscriptiongroups.active = true AND account_subscriptiongroups.user_id = account_user.id

对此查询:

代码语言:javascript
运行
复制
SELECT 
      account_user.id as user_id, account_user.email, account_user.first_name, account_user.last_name, account_user.phone,
      account_subscriptiongroup.id as sub_group_id,
      account_adminaction.description,
      account_adminaction.id as admin_action_id,
      account_adminaction.created_on  as subscription_ended_on
    
    FROM 
      account_adminaction
    
    LEFT JOIN
      account_user ON account_user.id = account_adminaction.user_id
    LEFT JOIN 
      account_subscriptiongroup ON account_adminaction.sub_group_id = account_subscriptiongroup.id
    
    WHERE 
      account_adminaction.created_on >= '2021-04-07' AND account_adminaction.created_on <= '2021-04-13' AND
      ((account_adminaction.description LIKE 'Arrêt de l''abonnement%') OR (account_adminaction.description LIKE 'L''utilisateur a arrêté%'))
    
    ORDER BY
      subscription_ended_on

我试过像这样添加一个左连接:

代码语言:javascript
运行
复制
LEFT JOIN 
  account_subscriptiongroup all_sg ON account_user.id = account_subscriptiongroup.user_id

在WHERE语句中使用这一行:

代码语言:javascript
运行
复制
AND all_sg.active = true

在我的选择中这一行:

代码语言:javascript
运行
复制
COUNT(all_sg.id)

但我发现了一个错误:

代码语言:javascript
运行
复制
ERROR:  column "account_user.id" must appear in the GROUP BY clause or be used in an aggregate function
LINE 2:   account_user.id as user_id, account_user.email, account_us...
          ^

我不明白我怎么能把这个动作做好

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-04-14 13:22:20

要计数某件事,您需要指定一个应用该计数的组。因此,您选择的每一列(而不是在聚合函数中使用,如COUNT或SUM),都需要在GROUP BY子句中提及。

或者换句话说:非聚合列必须应用于包含在特定计数中的所有行。

因此,在WHEREORDER BY子句之间添加一个GROUP BY子句:

代码语言:javascript
运行
复制
    GROUP BY account_user.id, account_user.email, account_user.first_name, account_user.last_name, account_user.phone,
      account_subscriptiongroup.id,
      account_adminaction.description,
      account_adminaction.id,
      account_adminaction.created_on

另一方面,如果您希望从另一个表中进行计数,则可以添加一个子选择:

代码语言:javascript
运行
复制
SELECT 
      account_user.id as user_id, account_user.email, account_user.first_name, account_user.last_name, account_user.phone,
      account_subscriptiongroup.id as sub_group_id,
      account_adminaction.description,
      account_adminaction.id as admin_action_id,
      account_adminaction.created_on  as subscription_ended_on,
      (SELECT COUNT(*) 
         FROM account_subscriptiongroups 
         WHERE account_subscriptiongroups.active = true 
           AND account_subscriptiongroups.user_id = account_user.id) AS groupcount
    FROM 
      account_adminaction

    LEFT JOIN
      account_user ON account_user.id = account_adminaction.user_id
票数 2
EN

Stack Overflow用户

发布于 2021-04-14 13:34:12

可以将联接保留到进行分组和计数的派生表中:

代码语言:javascript
运行
复制
SELECT au.id as user_id, au.email, au.first_name, au.last_name, au.phone,
       asg.id as sub_group_id,
       ad.description,
       ad.id as admin_action_id,
       ad.created_on  as subscription_ended_on,
       asgc.num_groups
FROM account_adminaction ad
    LEFT JOIN account_user au ON au.id = ad.user_id
    LEFT JOIN account_subscriptiongroups asg on ON ad.sub_group_id = asg.id
    LEFT JOIN (
      SELECT user_id, count(*) as num_groups
      FROM account_subscriptiongroups ag
      WHERE ag.active
      GROUP by user_id
    ) asgc on asgc.user_id = au.id
WHERE ad.created_on >= '2021-04-07' 
  AND ad.created_on <= '2021-04-13' 
  AND ((ad.description LIKE 'Arrêt de l''abonnement%') OR (ad.description LIKE 'L''utilisateur a arrêté%'))
ORDER BY subscription_ended_on

对我来说还不完全清楚,您想要计算的是什么,但是另一个选项(可能更慢)可能是使用一个窗口函数和一个filter子句:

代码语言:javascript
运行
复制
count(*) filter (where asg.active) over (partition by asg.user_id) as num_groups
票数 0
EN

Stack Overflow用户

发布于 2021-04-14 14:06:25

编辑:我的答案与a_horse_with_no_name提交的相同

有两个答案,一个是字面上的答案,一个只是解决你提出的问题,另一个是质疑你所要求的是否真的是你想要的。

简单回答:修改所需的查询,将user_id添加到Where子句中的user_id。现在,您有了一个表,该表可以左加入到其他较大的查询中。

代码语言:javascript
运行
复制
...
Left Join (Select user_id, count(*) as total_count
                   From account_subscriptiongroup
                   Where account_subscriptiongroups.active = true
                   Group By user_id) Z
    On Z.user_id=account_user.id

我怀疑这个数字是否是你真正想要的。这将计算所有时间的每个account_subscriptiongroup条目,但只计算活动条目。更大的查询带来非活动记录和活动记录,因此,如果您的目标是创建一个百分比分母,您将在这里混合“苹果和桔子”。

如果您决定要按用户对查询中的记录进行总计,则可以在不添加任何表的情况下向较大的查询中添加多一个元素。使用这样的窗口函数:

代码语言:javascript
运行
复制
Select ..., Sum(Case When account_subscriptiongroup.active Then 1 else 0 End) Over (Group By account_user.id) as total count

这只是计算日期范围内的记录和具有所需操作的记录。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67092255

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档