SQL Server 2008. Порядок повторяется, только если предыдущий отличается - PullRequest
0 голосов
/ 05 ноября 2018

Допустим, у меня есть эта таблица:

Price   | OrderDate   | OrderID
--------+-------------+-----
5.50000 | 2017-11-02  | 77319 
5.30000 | 2017-11-02  | 77320
5.50000 | 2017-11-09  | 77463
5.50000 | 2017-11-16  | 77633
5.50000 | 2017-11-23  | 77839
5.25000 | 2017-11-23  | 77840
5.35000 | 2017-11-30  | 78012
5.50000 | 2017-12-07  | 78138
5.50000 | 2017-12-14  | 78283

Мне нужно получить этот результат

Price   | OrderDate   | OrderID
--------+-------------+--------
5.50000  2017-11-02     77319 
5.30000  2017-11-02     77320
5.50000  2017-11-09     77463
5.25000  2017-11-23     77840
5.35000  2017-11-30     78012
5.50000  2017-12-07     78138

Значения выделены жирным шрифтом, мне нужно сгруппировать и получить только 1 строку. Порядок таблицы должен соответствовать результату.

Я понятия не имею, как это сделать.

Есть идеи?

Спасибо!

Ответы [ 4 ]

0 голосов
/ 05 ноября 2018

Это неэффективно, но это может быть легко понять, и в реальной жизни вы просто не сможете увидеть его неэффективность.

SELECT
    Price
    ,OrderDate
    ,OrderID
FROM TableName
WHERE Price <> ISNULL((SELECT TOP 1 Price FROM TableName T2 WHERE T2.OrderID < TableName.OrderID ORDER BY OrderID DESC), -1)

Кишки в предложении WHERE. Для каждой записи он находит цену предыдущей записи на основе [OrderID]. Если они отличаются, он включает их. Вы должны включить ISNULL, потому что первая запись не имеет предыдущей записи.

0 голосов
/ 05 ноября 2018

Вы можете использовать оконную функцию lag, чтобы получить цену предыдущей строки, и пропустить строки, в которых цена не изменилась:

SELECT   price, orderid, orderdate
FROM     (SELECT price, orderid, orderdate,
                 LAG(price) OVER(ORDER BY orderid ASC) AS prev_price
          FROM   mytable)
WHERE    price <> prev_price OR prev_price IS NULL
ORDER BY orderid ASC
0 голосов
/ 05 ноября 2018

Если ваша версия SQL Server 2008 и не поддерживает LAG оконную функцию.

Вы можете попробовать использовать подзапрос вместо LAG оконной функции.

SELECT Price,OrderDate,OrderID 
FROM (
    SELECT *,(select top 1 Price FROM T tt where tt.OrderID < t1.OrderID order by tt.OrderID desc) preval
    FROM T t1
) t1
WHERE preval <> Price or preval IS NULL

sqlfiddle

0 голосов
/ 05 ноября 2018

Предполагая, что вы можете использовать lag():

with data as (
    select *, lag(Price) over (order by OrderId) as lastPrice
    from T
)
select *
from data
where coalesce(Price, -1) <> lastPrice;

В противном случае, при условии, что вы можете использовать cross apply:

select t.*
from T t cross apply (
    select max(OrderId) priorOrderId from T t2 where t2.OrderId < t.OrderId
) left outer join T t3 on t3.OrderId = t2.priorOrderId
where coalesce(t3.Price, -1) <> t.Price;

Что еще можно переписать:

with data as (
    select *, (select max(OrderID from T t2 where t2.OrderId < t.OrderId) as priorOrderId
    from T t
)
select d.*
from data d left outer join T t on t.OrderId = d.priorOrderId
where coalesce(t.Price, -1) <> d.Price;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...