Возможности SQL: возможно ли выдавливать строки по значению и комбинировать таблицы по своему усмотрению? - PullRequest
0 голосов
/ 29 октября 2019

Предположим, у меня есть следующая таблица sql:

// foo

// columns 
ID 
DATE
SIZE
LIFETIME

Где foo представляет размер и дату, когда объект был удален с диска.

Предположим, у меня есть вторая таблица,

// bar
ID
DATE
SIZE

Где bar - это просто таблица, для которой каждый день на диске находился конкретный объект (и покрытие может быть неполным), информацияо размере объекта на только в этот день .


Прямо сейчас я делаю следующее вне SQL-запросов, и это занимает очень много времени: для каждого идентификатора в foo выдавить последний известный размер в строки "LIFETIME" (где 1 строка становитсяN строк для времени жизни N, с последним известным размером).

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


Можно ли выполнить это вычисление в запросе SQL? Другими словами: будет ли это пустой тратой времени на изучение?



Например, для простоты используются целые числа, а не дни:

// foo initial
ID DATE SIZE LIFETIME
a,1000,20.5,2
b,500,40.8,4

// foo after "extrusion" with last known size value
ID DATE SIZE LIFETIME
a,1000,20.5,2
a,999,20.5,1
a,998,20.5,0
b,500,40.8,4
b,499,40.8,3
b,498,40.8,2
b,497,40.8,1
b,496,40.8,0


// bar initial
ID DATE SIZE
a,998,2.0
b,499,34.0
b,498,30.0
b,496,10.0

И окончательные данные foobar:

// foobar combined
ID DATE SIZE LIFETIME
a,1000,20.5,2
a,999,20.5,1
a,998,2.0,0
b,500,40.8,4
b,499,34.0,3
b,498,30.0,2
b,497,40.8,1 // if this could have the least neighboring size value with id b
b,496,10.0,0 // that would be amazing, but thought this would be a good start

// defining least neighboring size value: 
//    Given
c,26,72 // obj c @ time 35 with size 72
c,23,35 // obj c @ time 23 with size 35

// then the extrusion would be:
c,26,72,j
c,25,35,j-1
c,24,35,j-2
c,23,35,j-3

1 Ответ

0 голосов
/ 30 октября 2019
with numbers as (select n from ...), /* values from 1 to max necessary */
select *
from foo f inner join numbers z on z.n <= f.lifetime
    cross apply (
        select top 1 size from bar b
        where b.id = f.id and f.date <= z.n
        order by z.n desc
    ) s
...