【问题标题】:Get the sum of all rows only once per userid每个用户 ID 只获取所有行的总和一次
【发布时间】:2019-01-17 20:36:47
【问题描述】:

我得到registration 表中所有行的总和。表结构如下:

row_id  row_registration_fee  row_amount  row_class  row_user_id
1          200                 1000         18           1
2          200                 2510         18           1
3            0                 1600         19           2
4            0                 1500         19           1
5          200                 1254         19           3
6          200                 3000         19           1
7          200                 2000         19           1
8            0                  100         20           1
9            0                  300         20           2

一个用户可以有多个注册费。我需要通过row_class 得到所有row_registration_fee 的总和。结果应该是这样的:

row_registration_fee  row_class
       200                18
       400                19
         0                20

我的选择:

SELECT (COUNT(DISTINCT(row_user_id))* 200) as 'fee' 
FROM registration 
WHERE row_registration_fee  > 0  
GROUP BY row_class

这里有没有更好的查询可以给出类似上述示例的结果?

使用 PHP 中的 foreach 循环,结果将显示在表格行中。截至目前,它只会给我两个注册费结果,row_class 18row_class 19 它不包括row_class 20,因为它只选择付费用户。

补充说明:注册费为2个或以上的用户,如果用户总共有400个费用,则应该只计算200个。

【问题讨论】:

  • row_class 18 的结果应该是200?在您的表格中,我看到两行带有row_class = 18row_registration_fee 的此类是200200,所以您应该得到400 否?
  • @Mickael Leger 我认为 op 想要忽略重复注册(按 row_user_id 和 row_class)
  • 我们可以假设最高 id 是每个用户最准确的费用吗?
  • @P.Salmon 不,逻辑是获取用户的总费用,如果total fee > 200 则应包括在内以计算他的费用。
  • 所以如果一个用户注册一个类 3 次 2 为 200 和 1 为 300 的结果应该是 500?

标签: mysql sql


【解决方案1】:

要获得这些预期结果,在我看来,您首先需要获取每个 (row_registration_fee, row_class, row_user_id) 元组的唯一记录。
为此,您可以使用带有 DISTINCT 的子查询。

然后将 row_registration_fee 相加。

SELECT 
 SUM(row_registration_fee) as fee, 
 row_class
FROM
(
   SELECT DISTINCT row_class, row_user_id, row_registration_fee
   FROM registration
) q
GROUP BY row_class

或通过 GROUP BY 获得 MAX 费用。

SELECT 
 SUM(max_fee) as fee, 
 row_class
FROM
(
   SELECT 
    row_class, row_user_id,
    MAX(row_registration_fee) as max_fee
   FROM registration
   GROUP BY 
    row_class, row_user_id
) q
GROUP BY row_class

但是要修复您当前的查询,您可以删除该 WHERE 子句。
然后使用 CASE WHEN 在零 row_registration_fee 上返回 NULL。
因为按值计数不计算 NULL。

SELECT 
 COUNT(DISTINCT CASE WHEN row_registration_fee = 0 THEN row_user_id END) * 200 as fee,
 row_class
FROM registration
GROUP BY row_class

【讨论】:

  • 需要一个 from 子句(在左括号之前),否则没问题。
  • @P.Salmon 谢谢。这是一个简单的词,但查询确实需要它。 :)
  • 谢谢!
  • @c.k,谢谢。如果您有固定费用,我认为第二个查询将是最好的。因为如果每个 row_user_id 的 row_registration_fee 不同,第一个会给出不同的结果。然后您必须更改获得最高或最新费用的查询。
  • 是的,我有固定的注册费用,即 200。
【解决方案2】:

你需要按两列分组,取sum

select row_class, sum(row_registration_fee)
from registration
group by row_class, row_user_id

【讨论】:

    【解决方案3】:
       SELECT SUM(row_registration_fee), row_class, row_user_id
        FROM registration 
        WHERE row_registration_fee  > 0
        GROUP BY row_class, row_user_id;
    

    是的,按两列分组,您可以按班级和用户获得。

    【讨论】:

      【解决方案4】:

      另一种方法可能是查找最近的 row_id。在这种情况下,我已经更改了数据,因此第一个条目似乎是一个错误(费用 = 300),然后是第二个条目的正确金额。

      drop table if exists t;
      create table t(
      row_id  int,row_registration_fee  int,row_amount int, row_class int, row_user_id int);
      insert into t values
      (1    ,      300  ,               1000 ,        18    ,       1),
      (2    ,      200  ,               2510 ,        18    ,       1),
      (3    ,        0  ,               1600 ,        19    ,       2),
      (4    ,        0  ,               1500 ,        19    ,       1),
      (5    ,      200  ,               1254 ,        19    ,       3),
      (6    ,      200  ,               3000 ,        19    ,       1),
      (7    ,      200  ,               2000 ,        19    ,       1),
      (8    ,        0  ,                100 ,        20    ,       1),
      (9    ,        0  ,                300 ,        20    ,       2)
      ;
      
      select sum(row_registration_fee),row_class
      from
      (
      select t.row_class,t.row_registration_fee
      from t
      where t.row_id = (select max(row_id) from t t1 where t1.row_user_id = t.row_user_id and t1.row_class = t.row_class)
      ) a
      group by row_class;
      
      +---------------------------+-----------+
      | sum(row_registration_fee) | row_class |
      +---------------------------+-----------+
      |                       200 |        18 |
      |                       400 |        19 |
      |                         0 |        20 |
      +---------------------------+-----------+
      3 rows in set (0.00 sec)
      

      【讨论】:

        猜你喜欢
        • 2021-01-27
        • 1970-01-01
        • 1970-01-01
        • 2023-03-15
        • 1970-01-01
        • 2018-08-28
        • 2019-07-07
        • 2014-06-17
        • 1970-01-01
        相关资源
        最近更新 更多