【问题标题】:Order selection订单选择
【发布时间】:2017-10-14 22:56:48
【问题描述】:
CustID Sequencing Total
2 1 10
4 2 20
3 2 30
4 4 40
5 8 50

我希望选择订单金额>=前订单金额的客户,如何实现?

【问题讨论】:

  • 编辑您的问题并显示您想要的结果。同时标记您正在使用的数据库。
  • 逻辑还是不清楚。
  • @GordonLinoff 意思是对于每个客户 id,我们发现订单序列比前一个最大的订单属于该客户,如果订单数量大于我们想要的结果。

标签: sql sql-server sqlite


【解决方案1】:

使用ANSI标准lag()函数,可以选择值增加的所有场合:

select t.*
from (select t.*,
             lag(amount) over (partition by customer order by order_sequence) as prev_amount
      from t
     ) t
where amount > prev_amount;

编辑:

对于修改后的问题,您可以使用first_value()。但是,我不是 100% 清楚确切的逻辑:

select t.*
from (select t.*,
             first_value(amount) over (partition by customer order by order_sequence desc) as last_amount
      from t
     ) t
where amount > last_amount;

【讨论】:

  • 对不起,这是最后一个订单而不是上一个订单,是否可以在不使用延迟和分区依据的情况下使其变得简单?
【解决方案2】:

对于 2005、2008 版本:

declare @t table(cust int, ord_s int, ord_a int);
insert @t values
(1,1,30), (1,3,40), (2,1,40), (2,6,30), (3,4,15),
(3,7,60),(3,8,50),(4,2,32),(4,5,2),(4,7,4);

with cte as
(
select row_number() over(partition by cust order by ord_s) as rn, *
from @t
)

select c1.cust,
        c1.ord_s,
        c1.ord_a,
        c2.ord_a as prv
from cte as c1 join cte as c2
         on c1.cust = c2.cust and  c1.rn = c2.rn + 1
where c1.ord_a > c2.ord_a;

听到的想法总是一样的,你应该找到之前的订单,如果你不能使用lag,你可以像上面那样枚举每个客户的订单并加入相邻的订单,如果你不能使用甚至row_number,你可以搜索最近的值不如现在这样:

select tt1.*
from 
(
select *,
       (select max(t2.ord_s) from @t t2 where t2.cust = t1.cust and t2.ord_s < t1.ord_s) as prv
from @t t1
) tt1 
join @t tt2
    on tt1.cust = tt2.cust and tt1.prv = tt2.ord_s
where tt1.ord_a > tt2.ord_a;

【讨论】:

    【解决方案3】:
    DECLARE @Temp table(cust int, ord_seq int, ord_amt int);
    insert @Temp values
    (1,1,30), (1,3,40), (2,1,40), (2,6,30), (3,4,15),
    (3,7,60),(3,8,50),(4,2,32),(4,5,2),(4,7,4);
    
    SELECT 
         Seq AS SeqNo
        ,cust AS CustomerID
        ,ord_seq AS OrderSequence
        ,ord_amt AS OrderAmount
    FROM (
        SELECT *,CASE WHEN LAGord_amt IS NULL THEN 0
                ELSE 1
                END As  LAGord_amt1
            ,ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS Seq
            ,CASE 
                WHEN ord_amt > LAGord_amt
                    THEN ord_amt
                ELSE 0
                END Lagval
        FROM (
            SELECT *,LAG(ord_amt) OVER (PARTITION BY cust ORDER BY ord_seq) As LAGord_amt
            FROM @Temp
            ) Dt
        ) Dt2
    WHERE Dt2.LAGord_amt1 = 1
        AND Lagval <> 0
    

    输出

        SeqNo   CustomerID  OrderSequence   OrderAmount
        ---------------------------------------------
         2          1           3               40
         6          3           7               60
         10         4           7               4
    

    【讨论】:

      猜你喜欢
      • 2023-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-02
      相关资源
      最近更新 更多