MySQL总和基于一个条件

时间:2014-10-27 01:06:57

标签: mysql sum

我在表格中有数据,它提供原始事件和这样的产品计数:

|order_id|customer_id|product_count|
|1       |1          |2            |
|2       |1          |-1           |
|3       |1          |3            |
|4       |1          |-1           |
|5       |2          |-1           |
|6       |2          |2            |
|7       |2          |-1           |
|8       |3          |-1           |
|9       |3          |-1           |
|10      |3          |-1           |

我想要这样的结果:(只有在第一个正值之后的和值)

|customer_id|SUM(remaining_product)|
|1          |3                     |
|2          |1                     |
|3          |0                     |

使用此查询我可以返回所有总和:

SELECT customer_id, SUM(product_count) 
FROM table 
GROUP BY customer_id;

我需要的是product_count的总和,它应该只在一个正值之后开始。 因此,对于客户1,第一个订单是积极的,因此其2-1 + 3-1 = 3 对于cutomer 2,第一顺序为负,所以忽略它,它将以2-1 = 1开始 对于客户3,我们从未看到正值,因此我们保持在0。

3 个答案:

答案 0 :(得分:1)

我通过从子查询开始来解决这个问题,该子查询检索每个客户ID的最小正行。使用MIN()函数足够简单:

SELECT MIN(order_id) AS minOrderID, customer_id
FROM myTable
WHERE product_count > 0
GROUP BY customer_id

然后我将其与原始表一起加入,以获取每个组的order_id之后或之后的行。这样,您可以对在正行之后开始的所有行求和。然后查询变为:

SELECT t.customer_id, SUM(t.product_count)
FROM myTable t
JOIN (SELECT MIN(order_id) AS minOrderID, customer_id
  FROM myTable
  WHERE product_count > 0
  GROUP BY customer_id) w
ON w.customer_id = t.customer_id AND t.order_id >= w.minOrderID
GROUP BY t.customer_id;

您必须(自然地)加入customer_id上的表,但条件是order_id大于或等于具有正产品数的最小order_id。这样只会将之后的行相加。

如果您不关心0的customer_ids,则此查询就足够了。但是,如果您还希望显示0行,我会使用查询来执行外部联接,以获取每个客户ID。您需要一个IFNULL()函数来检查上面第二个查询中没有行的customer_ids。

最后,我们有了这个:

SELECT k.customer_id, IFNULL(f.productSUM, 0) AS sumOfProducts
FROM(SELECT DISTINCT customer_id
     FROM myTable) k
LEFT JOIN(SELECT t.customer_id, SUM(t.product_count) AS productSUM
          FROM myTable t
          JOIN (SELECT MIN(order_id) AS minOrderID, customer_id
                FROM myTable
                WHERE product_count > 0
                GROUP BY customer_id) w
                ON w.customer_id = t.customer_id AND t.order_id >= w.minOrderID
                GROUP BY t.customer_id) f
ON k.customer_id = f.customer_id;

不管你相信与否。这是SQL Fiddle

答案 1 :(得分:1)

这里的想法是为每个客户计算第一个正数(product_count > 0} order_id,然后为product_count计算order_id >= first_positive_order_id个值:

SELECT t.customer_id, SUM(
  CASE WHEN m.first_positive_order_id IS NOT NULL
        AND t.order_id >= m.first_positive_order_id
       THEN t.product_count
       ELSE 0
  END) as remaining_count
FROM `table` t
LEFT JOIN (
   SELECT customer_id, MIN(order_id) AS first_positive_order_id
     FROM `table`
     WHERE product_count > 0
     GROUP BY customer_id
) m ON m.customer_id = t.customer_id
GROUP BY customer_id

测试它:SQL Fiddle

答案 2 :(得分:0)

select customer_id, 
       case when sum(product_count) < 0 
            then 0 
            else sum(product_count) 
       end as sum
from table 
group by customer_id;