S
S
silverxak2018-04-09 19:52:07
SQL
silverxak, 2018-04-09 19:52:07

Sampling aggregated values ​​given null?

Hello!
There is a table of moving books from shelf to shelf, let's say:

create table moves (
    moves_id int not null identity,
    book_id int not null,           --Книга
    rack_id int not null,           --Стеллаж
    board_id int not null,          --Полка
    date_from datetime not null,    --Дата поступления на стеллаж и полку (равно предыдущему date_to)
    date_to datetime null,          --Дата забора со стеллажа и полки (равно предыдущему date_from)
    primary key (moves_id)
)

For each book, output:
book_id     - Книгу
rack_id     - Стеллаж
date_from   - дату поступления на стеллаж вне зависимости от полки
date_to     - дату забора со стеллажа вне зависимости от полки

At the same time, it should be taken into account that the movement of books can be carried out both from rack to rack, and within one rack: from shelf to shelf.
If date_to is null, then the book is still on this rack and shelf.
Here is the test data on the example of one book:
insert into moves (book_id, rack_id, board_id, date_from, date_to) values
(8000, 56, 20, '01.02.2018 13:40:20.000', '21.02.2018 14:30:00.000'),
(8000, 56, 21, '21.02.2018 14:30:00.000', '10.03.2018 19:39:00.000'),
(8000, 56, 22, '10.03.2018 19:39:00.000', '15.03.2018 12:20:00.000'),
(8000, 60, 40, '15.03.2018 12:20:00.000', '16.03.2018 14:00:00.000'),
(8000, 60, 41, '16.03.2018 14:00:00.000', '19.03.2018 17:30:00.000'),
(8000, 60, 42, '19.03.2018 17:30:00.000', '01.04.2018 10:40:00.000'),
(8000, 56, 23, '01.04.2018 10:40:00.000', '05.04.2018 20:10:00.000'),
(8000, 56, 24, '05.04.2018 20:10:00.000', null)

I tried to aggregate in different ways, and through cte it doesn’t work out otherwise, I hit a dead end, tell me the solution, thanks in advance.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
alexalexes, 2018-04-09
@alexalexes

If you can reproduce the Oracle expression Rank() over (partition by ... order by ...) in MS SQL, it will be easy.

select last_move.book_id, last_move.rack_id, last_move.board_id,  -- последнее местонахождение книги
           first_move.date_from, -- дата первого появления на складе
           last_move.date_to -- дата последнего перемещения
from
-- подзапрос, получаем первые записи появления каждой книги на складе
(select *
   from (select t.*, rank() over (partition by t.book_id order by t.date_from) rnk
              from table t)
where rnk = 1) first_move

join
-- подзапрос, получаем последние записи перемещения каждой книги на складе
(select *
   from (select t.*, rank() over (partition by t.book_id order by t.date_from DESC) rnk
              from table t)
where rnk = 1) last_move

-- сопоставляем записи
on first_move.book_id = last_move.book_id

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question