#sql #sql-server
#sql #sql-server
Вопрос:
это одна итерация тестовых данных:
DECLARE @trial TABLE (id int)
INSERT INTO @trial (id)
VALUES (0), (0),(3), (0), (0),(0), (7), (0),(9), (0), (0),(12), (0), (0),(15)
select * from @trial
Числа всегда будут представлять собой последовательность 0 или номер строки. В любом наборе, если число не равно нулю, число всегда будет представлять строку, поэтому оно всегда будет увеличиваться.
Мне нужны 0, чтобы принять следующее максимальное значение. Таким образом, результат должен быть таким:
3
3
3
7
7
7
7
9
9
12
12
12
15
15
15
пожалуйста, помогите!!
Комментарии:
1. Какую СУБД вы используете?
2. я использую sql 2016
3. @charliealpha . . . «Мне нужны 0, чтобы принять следующее максимальное / предыдущее минимальное значение». Ваш вопрос неясен. Как вы узнаете, какое значение вы хотите?
4. это зависит от 1-й строки. если 1-я строка = 0, затем возьмите next max (если это имеет смысл). если 1-я строка <> 0, тогда возьмите предыдущую минуту. не требуется вносить изменения в значения строк <> 0.
5. @SteveC спасибо, я упростил вопрос.
Ответ №1:
Я думаю, это то, что вы ищете
declare @trial table (id int)
insert into @trial (id)
values (0), (0),(3), (0), (0),(0), (7), (0),(9), (0), (0),(12), (0), (0),(15) ;
;with
seq_cte as (select row_number() over (order by (select null)) rn from @trial),
break_cte as (select s.rn, isnull(t.id, 0) input_n, iif(isnull(t.id, 0)=0, 0, 1) seq_break,
lag(iif(isnull(t.id, 0)=0, 0, 1), 1, 0) over (order by s.rn) seq_break_lag
from seq_cte s left join @trial t on s.rn=t.id),
group_cte as (select *, sum(bc.seq_break_lag) over (order by bc.rn) break_grp from break_cte bc),
join_v_cte as (select id, (row_number() over (order by id))-1 jrn from @trial where id<>0)
select vc.id
from group_cte gc
join
join_v_cte vc on gc.break_grp=vc.jrn;
Результаты
id
3
3
3
7
7
7
7
9
9
12
12
12
15
15
15
Ответ №2:
Таблицы SQL представляют неупорядоченные наборы. Порядок отсутствует — и нет кумулятивного максимума — если у вас нет столбца, который определяет порядок.
Это легко включить, имея identity
столбец. Такой столбец сохранит порядок вставки, который, по-видимому, является тем, что вы хотите. Итак, это делает то, что вы хотите:
DECLARE @trial TABLE (id int identity, val int)
INSERT INTO @trial (val)
VALUES (1), (0),(0), (0), (0),(0), (7), (0),(9), (0), (0),(12), (0), (14),(0)
select * from @trial
select max(val) over (order by id) as running_max
from @trial
order by id;
Редактировать:
В ваших примерах данных вы хотите смотреть вперед, а также назад. Для этого вы можете использовать case
выражение, чтобы найти случаи, когда первые строки имеют 0
:
select (case when max(val) over (order by id) = 0
then min(case when val > 0 then val end) over (order by id desc)
else max(val) over (order by id)
end) as running_max
from trial
order by id;
Здесь находится db<>fiddle.
Комментарии:
1. Спасибо. итерация является результатом упорядоченного запроса. я вставлю идентификаторы в запрос, и это должно сработать! Спасибо!!
2. извините, что сказал слишком рано. это не сработало для 1-го набора данных. можете ли вы перепроверить? Спасибо.
3. 4-я, 5-я и 6-я строки оказались равными 3. их должно быть 7. спасибо за вашу помощь. есть какие-нибудь идеи? приветствия