当字段的总和等于值时获得最大日期

时间:2018-07-29 10:26:49

标签: sql

我在编写查询时遇到问题。
行数据如下:

DATE        CUSTOMER_ID AMOUNT
20170101    1           150
20170201    1           50
20170203    1           200
20170204    1           250
20170101    2           300
20170201    2           70

我想知道每个customer_id的金额总和何时(超过哪个日期)超过350, 如何编写此查询以得到这样的结果?

CUSTOMER_ID   MAX_DATE
1             20170203
2             20170201

谢谢

5 个答案:

答案 0 :(得分:2)

只需使用ANSI / ISO标准窗口函数来计算运行总和:

select t.*
from (select t.*,
             sum(t.amount) over (partition by t.customer_id order by t.date) as running_amount
      from t
     ) t
where running_amount - amount < 350 and
      running_amount >= 350;

如果由于某种原因您的数据库不支持此功能,则可以使用相关的子查询:

select t.*
from (select t.*,
             (select sum(t2.amount)
              from t t2
              where t2.customer_id =  t.customer_id and
                    t2.date <= t.date
             ) as running_amount
      from t
     ) t
where running_amount - amount < 350 and
      running_amount >= 350;

答案 1 :(得分:1)

ANSI SQL

用于测试:TSQL和MS SQL Server 2012

select 
  "CUSTOMER_ID",
  min("DATE")
FROM
(
 select 
  "CUSTOMER_ID",
  "DATE",
  (
  SELECT 
    sum(T02."AMOUNT") AMOUNT
  FROM "TABLE01" T02
  WHERE
     T01."CUSTOMER_ID" = T02."CUSTOMER_ID"
     AND T02."DATE" <= T01."DATE"
  ) "AMOUNT"
 from "TABLE01" T01
) T03
where
  T03."AMOUNT" > 350
group by
  "CUSTOMER_ID"
GO
CUSTOMER_ID | (No column name)   
----------: | :------------------
          1 | 03/02/2017 00:00:00
          2 | 01/02/2017 00:00:00

db <>提琴here

答案 2 :(得分:0)

DB-Fiddle

SELECT
    tmp.`CUSTOMER_ID`,
    MIN(tmp.`DATE`) as MAX_DATE
FROM
    (
        SELECT
            `DATE`,
            `CUSTOMER_ID`,
            `AMOUNT`,
            (
                SELECT SUM(`AMOUNT`) FROM tbl t2 WHERE t2.`DATE` <= t1.`DATE` AND `CUSTOMER_ID` = t1.`CUSTOMER_ID`
            ) AS SUM_UP
        FROM
            `tbl` t1
        ORDER BY
            `DATE` ASC
   ) tmp
WHERE
    tmp.`SUM_UP` > 350
GROUP BY
    tmp.`CUSTOMER_ID`

说明:

首先,我选择所有行,然后用所有SUM和ID子选择所有行,其中当前行DATE小于或等于客户的所有行。从此选项卡中,选择“最小日期”,该日期的当前总和为> 350

答案 3 :(得分:0)

我认为这不是一个简单的计算,您必须计算一些东西。我知道可以看到有些混杂,但我想逐步进行计算。作为第一步,如果我们能在您的方案中取得成功,我相信可以在性能方面做得更好。 如果有人可以改善我的查询,请编辑我的帖子;

不幸的是,我无法在计算机上尝试的解决方案在下面,我想它将为您带来预期的结果;

-- Get the start date of customers
SELECT MIN(DATE) AS DATE
    ,CUSTOMER_ID
INTO #table
FROM TABLE t1

-- Calculate all possible date and where is sum of amount greater than 350
SELECT t1.CUSTOMER_ID
    ,SUM(SELECT Amount FROM TABLE t3 WHERE t3.DATE BETWEEN t1.DATE
            AND t2.DATE) AS total
    ,t2.DATE AS DATE
INTO #tableCalculated
FROM #table t1
INNER JOIN TABLE t2 ON t.ID = t2.ID
    AND t1.DATE != t2.DATE
WHERE total > 350

-- SELECT Min amount and date for per Customer_ID
SELECT CUSTOMER_ID, MIN(DATE) AS DATE
FROM #tableCalculated
GROUP BY ID

答案 4 :(得分:-2)

SELECT CUSTOMER_ID, MIN(DATE) AS GOALDATE
FROM ( SELECT cd1.*, (SELECT SUM(AMOUNT)
                 FROM CustData cd2
                 WHERE cd2.CUSTOMER_ID = cd1.CUSTOMER_ID
                   AND cd2.DATE <= cd1.DATE) AS RUNNINGTOTAL
  FROM CustData cd1) AS custdata2
WHERE RUNNINGTOTAL >= 350
GROUP BY CUSTOMER_ID

DB Fiddle