2015-11-26 18 views
3

首先:我在之前提出的問題中發現了一些可能的問題答案,但遇到了讓它們正常工作的問題。我知道這個問題已經被問到了,但答案總是在工作代碼中使用的方法幾乎沒有解釋。找出總結值達到SQL中的某個檢查點的時間

所以:我已經找到了當客戶達到VIP狀態,當他的訂單值超過50萬。我有2個表是:一個有訂單ID,客戶ID和訂購日期,和第二位orderid,數量和單位價格。 我正在寫的查詢的結果應該是3個colums寬,一個用customerid,一個用true/false命名爲「VIP?」,第三個是獲得VIP狀態的日期(這是爲了把與前幾次總結了超過50 000)-the最後一個應該是空白,如果客戶沒有達到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

我不要求對問題的解決,我要求解決它的辦法,就如何的想法接近它。沒有問題,因爲還沒有解決方案。 我正在羅斯文數據庫上工作,我問的問題是關於在我的教科書中找到的練習,我不知道如何創建除視圖之外的任何東西(這不會對我很有幫助),也不能插入任何東西。 謝謝你的回答。 – Nech

+0

嗯,是的。我剛剛注意到我選擇了錯誤的標籤,對不起。 – Nech

+0

你正在使用哪個數據庫? – Utsav

回答

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

+0

''這個簡單的返回與最新日期的行:-) – dnoeth

1

不會使邏輯顯示'vip'和'貴賓日期'的答案複雜化。這將爲您提供每個客戶訂單的總額。

select o.orderid, o.customerid, o.orderdate, sum(od.quantity*od.unitprice) 'Total', ( select sum(od.quantity * od.unitprice) total from orders o2 join [Order Details] od2 on od2.orderid=o2.orderid where o2.orderID <= o.orderID and o2.customerid = o.customerid) 'RunningTotal' from orders o join [Order Details] od on od.orderid=o.orderid group by o.orderid, o.customerid, o.orderdate order by o.customerid

+0

您可以使用'sum(od.quantity * od.unitprice)(通過o.customerid order by o.orderdate分區)'' –

0

要回答你對如何處理的問題,你可以考慮去運行在每次更新所涉及的表,並設置了當閾值hit.This會設定日期的狀態的SQL觸發器當事件發生時。

另一種方法是使用存儲過程,其中您可以使用循環頂部遍歷記錄併到達日期。

可以根據數據量進行選擇,前者適用於極大量的數據。

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

相關問題