2013-04-10 101 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