2013-04-10 50 views
1

首先,我應該說我發現很難用幾個簡短的詞來表達下面的問題,因此這個可怕的問題題目。非常歡迎提出改進建議。通過...訂單查詢結果?

我們真正的問題...

考慮下面的示例,爲客戶和發票無序數據...

編輯我已經創建了以下

一個SQL Fiddle客戶資料

customer_id name 
------------------ 
1    Gary 
2    Jeremy 
3    Marcia 
4    Danielle 

發票數據

invoice_id customer_id created_date amount 
------------------------------------------------ 
1   1    2008-01-01  500.00 
2   1    2011-01-01  600.00 
3   1    2012-01-01  100.00 
4   1    2012-01-01  550.00 
5   2    2008-01-01  600.00 
6   2    2012-01-01  200.00 
7   2    2013-01-01  1000.00 
8   3    2012-01-01  300.00 
9   3    2013-01-01  100.00 
10   3    2009-01-01  250.00 
11   4    2010-01-01  300.00 
12   4    2011-01-01  700.00 
13   4    2012-01-01  500.00 

...怎麼會查詢被寫入到下面的方式返回數據...

  1. 第一行中的最古老的發票。如果同一年齡的發票超過1張,那麼年齡相同的發票中,發票金額最大。如果超過1張相同年齡和金額的發票,則分類變得無關緊要。
  2. 第二行中與第一行相同的客戶的下一個最早的發票。同樣,如果超過1張相同年齡的發票,發票金額最大。如果超過1張相同年齡和金額的發票,則分類變得無關緊要。
  3. 重複#2,直到該客戶沒有更多發票。
  4. 針對不同客戶的下一個最早的發票。如果超過1張相同的發票,那麼,那些年齡相同的發票,發票金額最大。如果超過1張相同年齡和金額的發票,則分類變得無關緊要。
  5. 對#4同一客戶重複#2。
  6. 重複#5,直到該客戶沒有更多發票。
  7. 重複#4,#5,#6

因此,對於上面的樣本數據,所希望的結果會是...

customer_name invoice_id created_date amount 
-------------------------------------------------- 
Jeremy   5   2008-01-01  600.00 <-- this is the joint "oldest" invoice with id 1 but has a greater amount. 
Jeremy   6   2012-01-01  200.00 <-- this is the next "oldest" invoice for the same customer as the previous row. 
Jeremy   7   2013-01-01  1000.00 
Gary   1   2008-01-01  500.00 <-- no more invoice for previous customer, so this is the next "oldest" invoice for a new customer 
Gary   2   2011-01-01  600.00 
Gary   4   2012-01-01  550.00 <-- same age as inv_id 3 but larger amount 
Gary   3   2012-01-01  100.00 
Marcia   10   2009-01-01  250.00 
Marcia   8   2012-01-01  300.00 
Marcia   9   2013-01-01  100.00 
Danielle  11   2010-01-01  300.00 
Danielle  12   2011-01-01  700.00 
Danielle  13   2012-01-01  500.00 

爲了得到更廣泛的背景爲這個問題,結果將被用於追蹤發票的付款,最老的和最「優先」的是最高優先級,但也可以看到所有客戶的發票分組在一起。

P.S.我用的MS SQL Server 2008工作

+0

我忘了顧客。我修復了我的查詢。客戶按名稱排序。 – 2013-04-10 09:47:45

+0

我更新了我的答案。我不知道sqlfiddle.com。這很棒 :)。 Thx分享。 – 2013-04-10 10:41:11

回答

1

希望這個作品:)

with ordering as 
(
    select 
    row_number() over (order by o.created_date asc, o.amount desc) num, 
    customer_id, 
    customer_name 
    from 
    (
    select 
    min(i.created_date) 
    over (partition by c.customer_id) as min_created_date, 
    max(i.amount) 
    over (partition by c.customer_id, i.created_date) max_date_amount, 
    c.name as customer_name, 
    c.customer_id as customer_id, 
    i.invoice_id, 
    i.created_date, 
    i.amount 
    from 
    invoice i 
    join customer c on i.customer_id = c.customer_id 
)o 
    where o.min_created_date = o.created_date 
    and o.max_date_amount = o.amount 
) 
select 
ord.customer_name, 
i.invoice_id, 
i.created_date, 
i.amount 
from 
ordering ord 
join invoice i on i.customer_id = ord.customer_id 
order by ord.num asc, i.created_date asc, i.amount desc; 
+0

恐怕不是。第一個結果行返回invoice_id 5是正確的,但下一行應該是同一個客戶的下一個最早的發票(id 6),但它是id 1,用於不同的客戶。 – 2013-04-10 09:51:44

+0

@SmallestDruid是的,我修正了這個問題。 – 2013-04-10 09:52:29

+0

編輯現在不會將發票編號5(最早的發票)作爲第一行(這是正確的)返回,但是代替了10(因爲第一個訂單是在客戶名稱上)。 – 2013-04-10 10:01:02

1

我只是會在這裏拋出此作爲替代已經接受的答案。

SELECT temp.name, 
    temp.Invoice_Id, 
    temp.created_Date, 
    temp.amount 
FROM(
    SELECT 
    c.name, 
    i.invoice_id, 
    i.created_date, 
    i.amount, 
    min(i.created_date) over (partition by c.customer_id) as min_created_date, 
    max(i.customer_id) over (partition by i.created_Date, i.amount) as customerId 
    FROM 
    Customer c 
    LEFT JOIN 
    Invoice i 
    on 
    c.customer_ID=i.Customer_ID 
) temp 

ORDER BY temp.min_created_date, 
    temp.customerId desc, 
    temp.created_Date, 
    temp.amount desc 
+0

這也給出了正確的結果,謝謝你的貢獻 – 2013-04-10 11:03:52