我在编写查询时遇到问题。
行数据如下:
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
谢谢
答案 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)
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