Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Помогите написать запрос  [new]
android1
Member

Откуда:
Сообщений: 10
Добрый день. Нужно написать запрос, который обрабатывает такие данные.
colA - расход, colB - доход
colA | colB
_________
1 | NULL
1 | NULL
NULL | 1
1 | NULL
1 | NULL
NULL | 1
1 | NULL

Рассмотрим эти данные как приход (colA) и расход (colB) одной единицы денег. В одной записи не могут быть 2 единицы.

Запрос должен вернуть - 1) сколько единиц мне нужно иметь в своем кармане, что осущестивать эти операции.
2) Сколько единиц останется после всех операций.

Должна соблюдаться строгая последовательность. На примере выше: рассмотрим первые 2 записи. Т.к. перед первыми 2 записями не было никаких приходов, мне нужно иметь 2 единицы, что осуществить операции.

На данных представленных выше результат будет:
1) 3 - нужно иметь 3 СВОИХ единицы для проведения операций
2) 0 - после проведения операций останется 0 единиц

Старался объяснить как можно лучше.

Спасибо за помощь.
4 ноя 11, 15:12    [11551201]     Ответить | Цитировать Сообщить модератору
 Re: Помогите написать запрос  [new]
aleks2
Guest
У тя проблемы с вычислением накопительной суммы и отысканием минимума оной?

ЗЫ. Кризис породили финансисты, не умеющие считать.
4 ноя 11, 16:37    [11551453]     Ответить | Цитировать Сообщить модератору
 Re: Помогите написать запрос  [new]
iap
Member

Откуда: Москва
Сообщений: 47145
android1,

в Вашем примере нет никакой "первой записи". И последней тоже нет.
Только неупорядоченная куча записей.
4 ноя 11, 16:38    [11551456]     Ответить | Цитировать Сообщить модератору
 Re: Помогите написать запрос  [new]
android1
Member

Откуда:
Сообщений: 10
iap
android1,

в Вашем примере нет никакой "первой записи". И последней тоже нет.
Только неупорядоченная куча записей.

1. 1 | NULL
2. 1 | NULL
3. NULL | 1
4. 1 | NULL
5. 1 | NULL
6. NULL | 1
7. 1 | NULL
4 ноя 11, 16:53    [11551504]     Ответить | Цитировать Сообщить модератору
 Re: Помогите написать запрос  [new]
Glory
Member

Откуда:
Сообщений: 104751
android1
1. 1 | NULL
2. 1 | NULL
3. NULL | 1
4. 1 | NULL
5. 1 | NULL
6. NULL | 1
7. 1 | NULL

И цифры 1,2 и тд - это у вас поле в таблице ?
4 ноя 11, 16:56    [11551513]     Ответить | Цитировать Сообщить модератору
 Re: Помогите написать запрос  [new]
android1
Member

Откуда:
Сообщений: 10
Glory
android1
1. 1 | NULL
2. 1 | NULL
3. NULL | 1
4. 1 | NULL
5. 1 | NULL
6. NULL | 1
7. 1 | NULL

И цифры 1,2 и тд - это у вас поле в таблице ?

Нет, цифры 1, 2. и т.д. - не поля таблицы.

Забыл добавить, что результат должен быть получен з помощью одного запроса, без использования функций, процедур и т.д.
4 ноя 11, 17:30    [11551599]     Ответить | Цитировать Сообщить модератору
 Re: Помогите написать запрос  [new]
Glory
Member

Откуда:
Сообщений: 104751
android1
Нет, цифры 1, 2. и т.д. - не поля таблицы.

Ну тогда по прежнему
"в Вашем примере нет никакой "первой записи". И последней тоже нет.
Только неупорядоченная куча записей."
4 ноя 11, 17:39    [11551619]     Ответить | Цитировать Сообщить модератору
 Re: Помогите написать запрос  [new]
android1
Member

Откуда:
Сообщений: 10
Glory
android1
Нет, цифры 1, 2. и т.д. - не поля таблицы.

Ну тогда по прежнему
"в Вашем примере нет никакой "первой записи". И последней тоже нет.
Только неупорядоченная куча записей."

Давайте тогда так: я упорядочил данные с помощью order by
Или же давайте, что эти числа 1, 2, 3, 4 есть колонкой в таблице.
4 ноя 11, 17:44    [11551629]     Ответить | Цитировать Сообщить модератору
 Re: Помогите написать запрос  [new]
Glory
Member

Откуда:
Сообщений: 104751
android1
Давайте тогда так: я упорядочил данные с помощью order by

Хорошо
Теперь расскажите нам, по какому полю идет этот order by
Потому что это поле должно участвовать в запросе, который вы хотите получить здесь
4 ноя 11, 17:48    [11551633]     Ответить | Цитировать Сообщить модератору
 Re: Помогите написать запрос  [new]
android1
Member

Откуда:
Сообщений: 10
Glory
android1
Давайте тогда так: я упорядочил данные с помощью order by

Хорошо
Теперь расскажите нам, по какому полю идет этот order by
Потому что это поле должно участвовать в запросе, который вы хотите получить здесь

Я понял Вас. Я хотел упростить условие, чтобы не усложнять понятие проблемы.

Давайте будем отталкиваться от таких данных:
1. 1 | NULL
2. 1 | NULL
3. NULL | 1
4. 1 | NULL
5. 1 | NULL
6. NULL | 1
7. 1 | NULL


1. 2. 3. 4. - столбец таблицы.
4 ноя 11, 18:06    [11551674]     Ответить | Цитировать Сообщить модератору
 Re: Помогите написать запрос  [new]
aleks2
Guest
declare @t table (n int primary key clustered, colA int, colB int)

;with
X as 
(select n, -colA as col FROM @t WHERE colA is not null
 UNION ALL
 select n, colB as col FROM @t WHERE colB is not null
)
,
Xn as ( select n, col, ROW_NUMBER() OVER(ORDER BY n, col) num  from X)
,
XnX as (
  select T.n, T.num, SUM(Z.col) Total FROM Xn T INNER JOIN Xn Z ON Z.num<=T.num GROUP BY T.n, T.num
)
select 
	(select MIN(Total) from XnX) [сколько единиц мне нужно иметь в своем кармане, что осущестивать эти операции]
	,
	(select SUM(col) FROM X) [Сколько единиц останется после всех операций]
 
4 ноя 11, 18:11    [11551683]     Ответить | Цитировать Сообщить модератору
 Re: Помогите написать запрос  [new]
NEKOS
Member

Откуда:
Сообщений: 194
android1
1) сколько единиц мне нужно иметь в своем кармане, что осущестивать эти операции.



create table #temp(id int identity(1,1) not null, currTime datetime default getdate(), a int, b int)

insert into #temp(a, b) values(1, NULL)
insert into #temp(a, b) values(1, NULL)
insert into #temp(a, b) values(NULL, 1)
insert into #temp(a, b) values(1, NULL)
insert into #temp(a, b) values(1, NULL)
insert into #temp(a, b) values(NULL, 1)
insert into #temp(a, b) values(1, NULL)
select * from #temp
order by currTime

declare @out int,
		@in int
declare @res int
set @res = 0
set @out = 0
set @in = 0
select 
@out = @out + case 
						when a = 1   then 1
						else 0
					end,
@in = @in + case 
						when b = 1   then 1
						else 0
					end,
			@res = @res + case 
						when a = 1 and @out - @res > @in then 1
						else 0
					end 
from #temp 
order by currTime
select @res
4 ноя 11, 18:49    [11551791]     Ответить | Цитировать Сообщить модератору
 Re: Помогите написать запрос  [new]
android1
Member

Откуда:
Сообщений: 10
aleks2
declare @t table (n int primary key clustered, colA int, colB int)

;with
X as 
(select n, -colA as col FROM @t WHERE colA is not null
 UNION ALL
 select n, colB as col FROM @t WHERE colB is not null
)
,
Xn as ( select n, col, ROW_NUMBER() OVER(ORDER BY n, col) num  from X)
,
XnX as (
  select T.n, T.num, SUM(Z.col) Total FROM Xn T INNER JOIN Xn Z ON Z.num<=T.num GROUP BY T.n, T.num
)
select 
	(select MIN(Total) from XnX) [сколько единиц мне нужно иметь в своем кармане, что осущестивать эти операции]
	,
	(select SUM(col) FROM X) [Сколько единиц останется после всех операций]
 

Ваш запрос при таких данных

1 NULL
1 NULL
NULL 1
NULL 1
NULL 1
1 NULL
1 NULL
1 NULL
1 NULL
NULL 1

Возращает -1, что есть совсем неправильный ответ.
4 ноя 11, 18:55    [11551803]     Ответить | Цитировать Сообщить модератору
 Re: Помогите написать запрос  [new]
aleks2
Guest
android1
Возращает -1, что есть совсем неправильный ответ.

Дарагуля, если твоих мозгов не хватает на замену знаков
(select n, colA as col FROM @t WHERE colA is not null
 UNION ALL
 select n, -colB as col FROM @t WHERE colB is not null
)
То какая, в сущности, разница?

А телепузиков, тьфу, телепатов нема.

>>colA - расход, colB - доход

>>Рассмотрим эти данные как приход (colA) и расход (colB)
4 ноя 11, 19:29    [11551909]     Ответить | Цитировать Сообщить модератору
 Re: Помогите написать запрос  [new]
android1
Member

Откуда:
Сообщений: 10
aleks2
android1
Возращает -1, что есть совсем неправильный ответ.

Дарагуля, если твоих мозгов не хватает на замену знаков
(select n, colA as col FROM @t WHERE colA is not null
 UNION ALL
 select n, -colB as col FROM @t WHERE colB is not null
)
То какая, в сущности, разница?

А телепузиков, тьфу, телепатов нема.

>>colA - расход, colB - доход

>>Рассмотрим эти данные как приход (colA) и расход (colB)

Перед тем как писать такие вещи, стоит проверить свой запрос.
4 ноя 11, 20:10    [11552014]     Ответить | Цитировать Сообщить модератору
 Re: Помогите написать запрос  [new]
iap
Member

Откуда: Москва
Сообщений: 47145
android1
Перед тем как писать такие вещи, стоит проверить свой запрос.
Перед тем, как делать такие замечания,
не мешало бы написать здесь свой собственный запрос.
Но даже в этом случае оно могло бы считаться, мягко говоря, некорректным (попросту хамским). IMHO
4 ноя 11, 20:20    [11552041]     Ответить | Цитировать Сообщить модератору
 Re: Помогите написать запрос  [new]
NEKOS
Member

Откуда:
Сообщений: 194
android1
Запрос должен вернуть - 1) сколько единиц мне нужно иметь в своем кармане, что осущестивать эти операции.



Вроде работает с помощю только одного селекта

create table #temp(id int identity(1,1) not null, currTime datetime default getdate(), a int, b int)

insert into #temp(a, b) values(1, NULL)
insert into #temp(a, b) values(1, NULL)
insert into #temp(a, b) values(NULL, 1)
insert into #temp(a, b) values(1, NULL)
insert into #temp(a, b) values(1, NULL)
insert into #temp(a, b) values(null, 1)
insert into #temp(a, b) values(1, NULL)

select * from #temp order by id

select MAX( t2.out_ - t2.in_)
from  #temp as t1
	cross apply  (
				select 
				sum(case when a = 1 then 1 else 0 end) as out_,
				sum(case when b = 1 then 1 else 0 end) as in_
				from #temp 
				where id < = t1.id
				) as t2 
7 ноя 11, 20:08    [11560413]     Ответить | Цитировать Сообщить модератору
 Re: Помогите написать запрос  [new]
NEKOS
Member

Откуда:
Сообщений: 194
android1
Запрос должен вернуть - 1) сколько единиц мне нужно иметь в своем кармане, что осущестивать эти операции.
2) Сколько единиц останется после всех операций.


Если сделать так, то вернет сразу все что надо и одним запросом. Если в таблице нет id то ее всегда можна сгерерировать в запросе.

select MAX( t2.out_ - t2.in_) as 'necessary', (SUM(a) - SUM(b) - MAX( t2.out_ - t2.in_)) * -1 as 'left'
7 ноя 11, 20:23    [11560461]     Ответить | Цитировать Сообщить модератору
 Re: Помогите написать запрос  [new]
Player_Nn
Member

Откуда:
Сообщений: 1
маленькая поправка :)

select case when MAX( t2.out_ - t2.in_)>0 then MAX( t2.out_ - t2.in_) else 0 end as 'necessary', (SUM(a) - SUM(b) - (case when MAX( t2.out_ - t2.in_)>0 then MAX( t2.out_ - t2.in_) else 0 end)) * -1 as 'left'
11 ноя 11, 22:41    [11585543]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить