首先:我在之前提出的问题中找到了我的问题的一些可能的答案,但我遇到了让它们正常工作的问题。我知道这个问题已经被问过,但答案总是工作代码,几乎没有解释所使用的方法。
所以:我必须找出客户何时达到VIP状态,即当他的订单价值超过5万时。我有2个表:一个有orderid,customerid和orderdate,第二个是orderid,数量和单价。 我写的查询结果应该是3个字符串宽,一个用customerid,一个用真/假命名"是VIP?",第三个是获得VIP的日期状态(与之前的订单相加的订单日期超过50 000) - 如果客户未达到VIP状态,则最后一个应为空白
select o.customerid, sum(od.quantity*od.unitprice),
case
when sum(od.quantity*od.unitprice)>50000 then 'VIP'
else 'Normal'
end as 'if vip'
from
orders o join [Order Details] od on od.orderid=o.orderid
group by o.customerid
就我所获得的代码而言,它返回了客户的状态,现在我需要获取发生的日期。
答案 0 :(得分:3)
您可以使用窗口函数轻松计算运行总计:
select o.customerid,
o.orderdate,
sum(od.quantity*od.unitprice) over (partition by o.customerid order by orderdate) as running_sum,
from orders o
join Order_Details od on od.orderid = o.orderid
order by customer_id, orderdate;
现在您需要找到一种方法来检测第一行,其中运行总计超过阈值:
一旦达到阈值,以下查询将开始以递减方式对行进行编号。这反过来意味着具有数字1的行是第一个越过阈值的行:
with totals as (
select o.customerid,
o.orderdate,
sum(od.quantity*od.unitprice) over (partition by o.customerid order by orderdate) as running_sum,
case
when
sum(od.quantity*od.unitprice) over (partition by o.customerid order by orderdate) > 50000 then row_number() over (partition by o.customerid order by orderdate desc)
else 0
end as rn
from orders o
join Order_Details od on od.orderid = o.orderid
)
select *
from totals
where rn = 1
order by customerid;
SQLFiddle示例:http://sqlfiddle.com/#!6/a7f18/3
答案 1 :(得分:3)
使用分析函数SUM OVER
获得累积和。然后添加聚合以查找最小日期:
with cte as
( select o.customerid,
o.orderdate,
case when sum(od.quantity*od.unitprice) -- running total
over (partition by o.customerid
order by orderdate
rows unbounded preceding) > 50000
then 'Y'
else 'N'
end as VIP
from orders o
join Order_Details od on od.orderid = o.orderid
)
select customerid,
MAX(VIP) AS "isVIP?", -- either 'N' or 'Y'
MIN(CASE WHEN VIP = 'Y' THEN orderdate END) AS VIP_date -- only when VIP status reached
from cte
group by customerid
order by customers;
请参阅fiddle
答案 2 :(得分:1)
不要用逻辑来复杂答案,以显示'vip'和'vip date'。这将为您提供每个客户订单的运行总计。
3.3.12
答案 3 :(得分:0)
要回答关于如何处理的问题,您可以考虑使用SQL触发器,该触发器在所涉及的表的每次更新时运行,并在达到阈值时设置状态。这将设置事件发生时的日期
另一种方法是使用存储过程,其中您可以对记录使用循环顶部迭代并到达日期。
可以根据数据量进行选择,前者适用于极大量的数据。