Получить два поля из параметра
RETURN(SELECT substring(',' + @param + ',', Number + 1,
charindex(',', ',' + @param + ',', Number + 1) - Number - 1)
AS Value
FROM Numbers
WHERE Number <= len(',' + @param + ',') - 1
AND substring(',' + @param + ',', Number, 1) = ',')
Как сделать, чтобы получить значения в два поля.
пример: inline_split_me('9, 12, 27, 38, 44, 55, 66, 77')
Поле1 | Поле2
9 | 12
27 | 38
44 | 55
66 | 77
если postgres, может это частично поможет
тогда здесь приведу под 2000.
set @param = '8, 9, 27, 38, 44, 55, 66, 77'
--1. Способ номер раз (с временной таблицей)
declare @t table (id int identity, pole int)
insert into @t(pole)
SELECT
val = convert(int,substring(',' + @param + ',',Number + 1,charindex(',', ',' + @param + ',', Number + 1) - Number - 1))
FROM
Numbers
WHERE
Number <= len(',' + @param + ',') - 1 AND substring(',' + @param + ',', Number, 1) = ','
select
pole1 = max(pole1),
pole2 = max(pole2)
from
(
select
rn = id%2,
gr = id%2+id,
pole1 = (case when id%2 = 1 then pole else null end),
pole2 = (case when id%2 = 0 then pole else null end)
from
@t
) t
group by
gr
--2. Способ номер два-с (в один запрос) // achtung govnokod detected!
select
pole1 = max(pole1),
pole2 = max(pole2)
from
(
select
t1.id,
pole1 = (case when count(*)%2 = 1 then t1.pole else null end),
pole2 = (case when count(*)%2 = 0 then t1.pole else null end),
rn = count(*)%2,
gr = count(*)%2+count(*)
from
(
SELECT
id = number,
pole = convert(int,substring(',' + @param + ',',Number + 1,charindex(',', ',' + @param + ',', Number + 1) - Number - 1))
FROM
Numbers
WHERE
Number <= len(',' + @param + ',') - 1 AND substring(',' + @param + ',', Number, 1) = ','
) t1
left join
(
SELECT
id = number,
pole = convert(int,substring(',' + @param + ',',Number + 1,charindex(',', ',' + @param + ',', Number + 1) - Number - 1))
FROM
Numbers
WHERE
Number <= len(',' + @param + ',') - 1 AND substring(',' + @param + ',', Number, 1) = ','
) t2 on t1.id >= t2.id
group by
t1.id,
t1.pole
) t
group by
gr
второй способ не рекомендую, первый быстрее и красивее.
есть еще третий способ - это парсить по два значения, и кейсом вытаскивать по разным полям, можете тож попробовать.
Теперь вопрос в другом. Возможно ли сделать следующее:
есть два параметра: первый - ид, второй количество записей. У нас есть массив параметров: ('0001,2,0002,2,0003,5').
Теперь нужно получить 2 -е записи для ид =0001, столько же для ид=0002 и пять для ид=0003.
Подскажите в какую сторону копать?
вот так можно
set @param = '0001,2,0002,2,0003,5'
--1. Способ номер раз (с временной таблицей)
declare @t table (id int identity, pole int)
insert into @t(pole)
SELECT
val = convert(int,substring(',' + @param + ',',Number + 1,charindex(',', ',' + @param + ',', Number + 1) - Number - 1))
FROM
Numbers
WHERE
Number <= len(',' + @param + ',') - 1 AND substring(',' + @param + ',', Number, 1) = ','
-- результат парсинга таблицы запишу во временную таблицу
-- для наглядности "задваивающего" запроса на практике
-- можно просто юзать поздапроз, без временной таблицы
declare @parsed table (a int, b int)
insert into @parsed(a,b)
select
pole1 = max(pole1),
pole2 = max(pole2)
from
(
select
rn = id%2,
gr = id%2+id,
pole1 = (case when id%2 = 1 then pole else null end),
pole2 = (case when id%2 = 0 then pole else null end)
from
@t
) t
group by
gr
-- "задваивающий" запрос
select *
from
@parsed p
join Numbers n on p.b >= n.Number
0001, 1, 125.25
0001, 2, 225.25
0001, 3, 325.25
0001, 4, 425.25
0001, 5, 525.25
0002, 1, 11.11
0002, 2, 121.11
0002, 3, 131.11
0002, 4, 141.11
0002, 5, 151.11
и если я указываю (0001, 2, 1, 0002,3, 3), то я получаю данные
0001, 2, 225.25
0002, 3, 131.11
0002, 4, 141.11
0002, 5, 151.11
где в списке:
1. 0001 - ИД клиента
2. 2 - идентификатор identity(1, 1)
3. 1 - количество записей начиная с идентификатора 2
для второго аккаунта будем брать 3 записи начиная с идентификатора 3
0001, 1, 125.25
0001, 2, 225.25
0001, 3, 325.25
0001, 4, 425.25
0001, 5, 525.25
0002, 1, 11.11
0002, 2, 121.11
0002, 3, 131.11
0002, 4, 141.11
0002, 5, 151.11
и если я указываю (0001, 2, 1, 0002,3, 3), то я получаю данные
0001, 2, 225.25
0002, 3, 131.11
0002, 4, 141.11
0002, 5, 151.11
где в списке:
1. 0001 - ИД клиента
2. 2 - идентификатор identity(1, 1)
3. 1 - количество записей начиная с идентификатора 2
для второго аккаунта будем брать 3 записи начиная с идентификатора 3
Какие данные?? Они реально так хранятся или это результат тех запроосв что я привел?? Или эти запросы призваны лишь для того чтобы распарсить параметры???
Давайте тогда оглашать всю задачу сразу целиком?! Потому как вы выдаете задачу порциями и это не лучшим образом сказывается на продуктивности и моих ответов и моем времени, и ваших вопросов и вашем времени соответственно. Т.к. когда задачу виднов целом - можно сформировать более эффективно решение.
Мне непонятно - что вам надо в итоге и какие данные у вас есть?
Для того чтобы правильно задавать вопросы потрудитесь почитать правила постинга в раздел
Кроме этого предоставьте:
1) исходные данные: скрипты создания тестовых таблиц и заполнения их тестовыми данными
2) подробное описание задачи: как вы работаете с данными, эдхок запросы, хранимые процедуры или функции? какие параметры, какие они могут иметь значения и т.д.
3) желаемый результат
Без этого - переливаем из пустого в порожнее.
Задача на аналитические функции с "окнами".
SomewherSomehow, в MS SQL аналитические функции вроде уже есть, а есть ли оконные выражения (rows between unbounded preceding and unbounded following)?
SomewherSomehow, в MS SQL аналитические функции вроде уже есть, а есть ли оконные выражения (rows between unbounded preceding and unbounded following)?
Не вроде, а точно есть. Просто если вы внимательно прочтете топик то увидите что у автора 2000 сиквел =( там нет аналит.функций.
Но дело даже не в этом, практически всегда можно выкрутиться, в ущерб изящности и скорости. А дело в том что автор тщательно скрывает свои конечные цели...выдает условия порциями, такими какими он считает это необходимо. И конечно эти порции только все портят, что я и пытаюсь донести до автора...
Задача с двумя параметрами была полная. Просто появилась новая, подобная первой.
Я понимаю ...
В скрипте есть функция, переделанная для трёх полей.
что нужно получить при данном параметре: ('00010,0056,3,00020,0082,2,00050,0160,2)
Три записи для Acct = 00010, начиная с Num = 0056. То есть (0056, 0057, 0058)
две записи для Acct = 00020, c Num = 0082, 0083.
две записи для Acct = 00050, Num = 0160, 0161.
Примечание. Записи в оригинале не отсортированы. Нужно брать следующую запись для определённого аккаунта, просто отсортировать по Num (Order by Acct, Num), так как записи могу быть удалены и следующий Num уже будет другой.
если удалить запись Acct = 00010, Num = 0057б то берём записи 0056,0058,0059.
Что ещё нужно для решения?
Тогда еще один вопрос, формат строки ('00010,0056,3,00020,0082,2,00050,0160,2') - вы задаете? если вы, то для простоты и скорости был бы удобен например такой формат: '[00010].[0056].[3],[00020].[0082].[2],[00050].[0160].[2]'
1. функция
returns table
as
return
(
select
Acct = parsename(p.val,3),
Num = parsename(p.val,2),
quant = convert(int, parsename(p.val,1))
from
(
select
val = substring(',' + @param + ',',Number + 1,charindex(',', ',' + @param + ',', Number + 1) - Number - 1)
from
Numbers
where
Number <= len(',' + @param + ',') - 1 AND substring(',' + @param + ',', Number, 1) = ','
) p
)
2. запрос
set @param ='[00010].[0056].[3],[00020].[0082].[2],[00050].[0160].[2]'
select *
from
(
select
rn = (
select count(*)
from
[B_Debit] dn
where
dn.Acct = d.Acct and
dn.Num <= d.Num and
dn.Num >= p.Num
),
p.quant,
d.*
from
[B_Debit] d
join dbo.uf_ParseBDebitQueryParams(@param) p on p.Acct = d.Acct and d.Num >= p.Num
) q
where
q.rn <= q.quant
пару примеров прогнал - работает, но тщательно не тестировал, это вы уж сами.
from
[B_Debit] d
join dbo.uf_ParseBDebitQueryParams(@param) p on p.Acct = d.Acct and d.Num >= p.Num
Ваш же перыдущий код для двух полей ('1234,011') работает быстрее: ~020 милисек.
Была сделана выборка для 121 записи.
Так что смотрите, что вы там еще делаете.
Изучайте планы. Возможно в вашей ситуации оптимизатор выбирает какой-то неудачный план.
Я тестировал с 212К записями. проблему решил, убрав Quantity, так как в производительности это не выигрывает
Переходите уже на более новую версию, там есть оконные функции типа row_number() т.д. - будет быстрее.
Не могу перейти. Не в моей компетенции. Оставил без quantity.
Спасибо за помощь