通过...订购查询结果?

时间:2013-04-10 09:33:16

标签: sql-server tsql

首先,我应该说,我发现很难用短语来表达以下问题,因此可怕的问题标题。建议改进是非常受欢迎的。

现在回到真正的问题......

鉴于以下示例,客户和发票的无序数据......

修改我为以下

创建了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
  8. 因此,对于上面的样本数据,期望的结果将是......

    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。

2 个答案:

答案 0 :(得分: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;

答案 1 :(得分: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