Выбор заказа


1

Для версий 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;

Идея слышать всегда одна и та же, вы должны найти предыдущий порядок, если вы не можете использовать лаг, вы перечисляете заказы внутри каждого клиента и присоединяетесь к смежным ордерам, как указано выше, если вы не можете использовать даже 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;

0

Используя стандартную lag()функцию ANSI , вы можете выбирать все случаи, когда значение увеличивается:

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;

0
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
SQL, SQL-сервер, SQLite,

sql,sql-server,sqlite,

1

Ответов: 3


1

Для версий 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;

Идея слышать всегда одна и та же, вы должны найти предыдущий порядок, если вы не можете использовать лаг, вы перечисляете заказы внутри каждого клиента и присоединяетесь к смежным ордерам, как указано выше, если вы не можете использовать даже 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;

0

Используя стандартную lag()функцию ANSI , вы можете выбирать все случаи, когда значение увеличивается:

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;

0
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
SQL, SQL-сервер, SQLite,
Похожие вопросы