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

Откуда:
Сообщений: 69031
Доброго времени суток. Сделал запрос, который возвращает мне общее количество чеков за определённый месяц.
select 
  b.base as [Филиал], 
  count(distinct op.smid) as [Чеки] 
from op
  inner join d on     op.docid = d.id 
  inner join b on     d.bid = b.id 
  inner join w on     op.goodsid = w.code 
where
  (
    b.id in (16,6,106,24,103,36,91,40,25)
  ) and
  (d.doctype = 6) and
  (d.docdate >= convert(datetime, '2013-06-01 00:00:00', 102)) and
  (d.docdate <= convert(datetime, '2013.06.30 23:59:59', 102)) and code between isnull(nullif(-1,-1),-2147483648)
   and isnull(nullif(-1,-1),2147483647) and f1 between isnull(nullif(-1,-1),-2147483648) and isnull(nullif(-1,-1),2147483647) 
   group by 
  b.base 

Сейчас настала необходимость добавить условие диапазона чеков. Пытался добавить вот такое условие:
(sum(op.Quantity*op.Price) between 8000 and 10000)

Но пишет, что в where нельзя использовать агр. функцию. в having если добавить, то будет считать уже всю сумму по всем чекам сразу. В каком месте и что нужно исправить(добавить)?
27 июн 13, 17:25    [14493397]     Ответить | Цитировать Сообщить модератору
 Re: Условие в запросе  [new]
Павел Воронцов
Member

Откуда: Новосибирск
Сообщений: 2392
Блог
Прогер_самоучка,

открой для себя having
27 июн 13, 17:32    [14493452]     Ответить | Цитировать Сообщить модератору
 Re: Условие в запросе  [new]
Прогер_самоучка
Member

Откуда:
Сообщений: 69031
Павел Воронцов
Прогер_самоучка,

открой для себя having

Вы до конца прочитали стартовый пост ?

Прогер_самоучка
в having если добавить, то будет считать уже всю сумму по всем чекам сразу. В каком месте и что нужно исправить(добавить)?
27 июн 13, 17:35    [14493469]     Ответить | Цитировать Сообщить модератору
 Re: Условие в запросе  [new]
daw
Member

Откуда: Муром -> Москва
Сообщений: 7381
> в having если добавить, то будет считать уже всю сумму по всем чекам сразу

с чего вы взяли? суммы будут считаться согласно группировке.
27 июн 13, 17:37    [14493495]     Ответить | Цитировать Сообщить модератору
 Re: Условие в запросе  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Прогер_самоучка
  (d.docdate >= convert(datetime, '2013-06-01 00:00:00', 102)) and
  (d.docdate <= convert(datetime, '2013.06.30 23:59:59', 102)) and code between isnull(nullif(-1,-1),-2147483648)
   and isnull(nullif(-1,-1),2147483647) and f1 between isnull(nullif(-1,-1),-2147483648) and isnull(nullif(-1,-1),2147483647)
Это вот что:
d.docdate>='20130601' and d.docdate<'20130701' and code is not null and f1 not null
27 июн 13, 17:38    [14493497]     Ответить | Цитировать Сообщить модератору
 Re: Условие в запросе  [new]
Прогер_самоучка
Member

Откуда:
Сообщений: 69031
daw
> в having если добавить, то будет считать уже всю сумму по всем чекам сразу

с чего вы взяли? суммы будут считаться согласно группировке.

Я понимаю, что согласно группировке. Ещё бы и понять каким образом.
27 июн 13, 17:47    [14493566]     Ответить | Цитировать Сообщить модератору
 Re: Условие в запросе  [new]
Прогер_самоучка
Member

Откуда:
Сообщений: 69031
iap
Прогер_самоучка
[/src]
Это вот что:
d.docdate>='20130601' and d.docdate<'20130701' and code is not null and f1 not null

Не совсем вас понял. Это вы спросили или поправили?)
27 июн 13, 17:49    [14493580]     Ответить | Цитировать Сообщить модератору
 Re: Условие в запросе  [new]
daw
Member

Откуда: Муром -> Москва
Сообщений: 7381
> Я понимаю, что согласно группировке. Ещё бы и понять каким образом.

то есть, что значит "каким"? ну выведите ее в select-листе:
select 
  b.base as [Филиал], 
  count(distinct op.smid) as [Чеки] 
  , sum(op.Quantity*op.Price)
from op
  inner join d on     op.docid = d.id 
  inner join b on     d.bid = b.id 
  inner join w on     op.goodsid = w.code 
where
  (
    b.id in (16,6,106,24,103,36,91,40,25)
  ) and
  (d.doctype = 6) and
  (d.docdate >= convert(datetime, '2013-06-01 00:00:00', 102)) and
  (d.docdate <= convert(datetime, '2013.06.30 23:59:59', 102)) and code between isnull(nullif(-1,-1),-2147483648)
   and isnull(nullif(-1,-1),2147483647) and f1 between isnull(nullif(-1,-1),-2147483648) and isnull(nullif(-1,-1),2147483647) 
   group by 
  b.base 


вот эта сумма и будет проверяться в having.
27 июн 13, 17:54    [14493604]     Ответить | Цитировать Сообщить модератору
 Re: Условие в запросе  [new]
Прогер_самоучка
Member

Откуда:
Сообщений: 69031
daw
> Я понимаю, что согласно группировке. Ещё бы и понять каким образом.

то есть, что значит "каким"? ну выведите ее в select-листе:

вот эта сумма и будет проверяться в having.

Выводил я так в select. Поэтому и говорю, что будет считать сумму сразу всех чеков.
Было вот так с добавлением having
select 
  b.base as [Филиал], 
  count(distinct op.smid) as [Чеки] 
  , sum(op.Quantity*op.Price)
from op
  inner join d on     op.docid = d.id 
  inner join b on     d.bid = b.id 
  inner join w on     op.goodsid = w.code 
where
  (
    b.id in (16,6,106,24,103,36,91,40,25)
  ) and
  (d.doctype = 6) and
  (d.docdate >= convert(datetime, '2013-06-01 00:00:00', 102)) and
  (d.docdate <= convert(datetime, '2013.06.30 23:59:59', 102)) and code between isnull(nullif(-1,-1),-2147483648)
   and isnull(nullif(-1,-1),2147483647) and f1 between isnull(nullif(-1,-1),-2147483648) and isnull(nullif(-1,-1),2147483647) 
   group by 
  b.base
 having   sum(op.Quantity*op.Price)
27 июн 13, 18:00    [14493653]     Ответить | Цитировать Сообщить модератору
 Re: Условие в запросе  [new]
Прогер_самоучка
Member

Откуда:
Сообщений: 69031
Прогер_самоучка
daw
> Я понимаю, что согласно группировке. Ещё бы и понять каким образом.

то есть, что значит "каким"? ну выведите ее в select-листе:

вот эта сумма и будет проверяться в having.

Выводил я так в select. Поэтому и говорю, что будет считать сумму сразу всех чеков.
Было вот так с добавлением having
select 
  b.base as [Филиал], 
  count(distinct op.smid) as [Чеки] 
  , sum(op.Quantity*op.Price)
from op
  inner join d on     op.docid = d.id 
  inner join b on     d.bid = b.id 
  inner join w on     op.goodsid = w.code 
where
  (
    b.id in (16,6,106,24,103,36,91,40,25)
  ) and
  (d.doctype = 6) and
  (d.docdate >= convert(datetime, '2013-06-01 00:00:00', 102)) and
  (d.docdate <= convert(datetime, '2013.06.30 23:59:59', 102)) and code between isnull(nullif(-1,-1),-2147483648)
   and isnull(nullif(-1,-1),2147483647) and f1 between isnull(nullif(-1,-1),-2147483648) and isnull(nullif(-1,-1),2147483647) 
   group by 
  b.base
 having   (sum(op.Quantity*op.Price) between 8000 and 10000)

З.Ы. Исправленный вариант
27 июн 13, 18:02    [14493667]     Ответить | Цитировать Сообщить модератору
 Re: Условие в запросе  [new]
daw
Member

Откуда: Муром -> Москва
Сообщений: 7381
> count(distinct op.smid) as [Чеки]

ааа, distinct. догадываюсь кажется. у вас join-ы "размножают" строки в op и суммы странные получаются?
27 июн 13, 18:02    [14493668]     Ответить | Цитировать Сообщить модератору
 Re: Условие в запросе  [new]
daw
Member

Откуда: Муром -> Москва
Сообщений: 7381
чтобы понятнее стало, вы уберите группировку и посмотрите, что выводится.
а "как бороться?" - ну, в вашем случае можно эти join-ы через exists переписать.
27 июн 13, 18:05    [14493685]     Ответить | Цитировать Сообщить модератору
 Re: Условие в запросе  [new]
Прогер_самоучка
Member

Откуда:
Сообщений: 69031
daw
> count(distinct op.smid) as [Чеки]

ааа, distinct. догадываюсь кажется. у вас join-ы "размножают" строки в op и суммы странные получаются?

Запредельные суммы получаются))) Количество чеков запрос выдаёт правильное. Вот как прописать сие условие, что на каждый чек, пока не соображу. Подозреваю, что эта "странная сумма" как раз и сумма сразу всех чеков.
27 июн 13, 18:07    [14493696]     Ответить | Цитировать Сообщить модератору
 Re: Условие в запросе  [new]
Cygapb-007
Member

Откуда:
Сообщений: 1677
daw
чтобы понятнее стало, вы уберите группировку и посмотрите, что выводится.
а "как бороться?" - ну, в вашем случае можно эти join-ы через exists переписать.
Добавил бы: уберите группировку и поставьте фильтр по какому-нибудь (может по очереди по разным) OP.SMID чтобы (на обозримом количестве данных) убедиться в отсутствии задваивания строк.
Может быть, и от DISTINCT в COUNT удастся избавиться :)
27 июн 13, 18:59    [14493933]     Ответить | Цитировать Сообщить модератору
 Re: Условие в запросе  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Прогер_самоучка
iap
пропущено...
Это вот что:
d.docdate>='20130601' and d.docdate<'20130701' and code is not null and f1 not null

Не совсем вас понял. Это вы спросили или поправили?)
Заменил на эквивалент
27 июн 13, 20:28    [14494156]     Ответить | Цитировать Сообщить модератору
 Re: Условие в запросе  [new]
Прогер_самоучка
Member

Откуда:
Сообщений: 69031
iap
Заменил на эквивалент
На самом деле это часть собирается в программе, поэтому там именно так :)
28 июн 13, 08:36    [14495249]     Ответить | Цитировать Сообщить модератору
 Re: Условие в запросе  [new]
Павел Воронцов
Member

Откуда: Новосибирск
Сообщений: 2392
Блог
Прогер_самоучка
Выводил я так в select. Поэтому и говорю, что будет считать сумму сразу всех чеков.
Было вот так с добавлением having
Не зная схему данных трудно угадывать, но скорей всего Вам нужно что-то типа
select 
  b.base as [Филиал], 
  sum(op1.chks) as [Чеки] 
from (select docid
             , goodsid
             , count(distinct smid) as chks
             , sum(op.Quantity*op.Price) as summ
from op
group by docid
             , goodsid) op1
  inner join d on     op1.docid = d.id 
  inner join b on     d.bid = b.id 
  inner join w on     op1.goodsid = w.code 
where
  (
    b.id in (16,6,106,24,103,36,91,40,25)
  ) and
  (d.doctype = 6) and
  (d.docdate >= convert(datetime, '2013-06-01 00:00:00', 102)) and
  (d.docdate <= convert(datetime, '2013.06.30 23:59:59', 102)) and code between isnull(nullif(-1,-1),-2147483648)
   and isnull(nullif(-1,-1),2147483647) and f1 between isnull(nullif(-1,-1),-2147483648) and isnull(nullif(-1,-1),2147483647) 
   group by 
  b.base
  having sum(op1.summ) between 8000 and 10000
28 июн 13, 09:13    [14495423]     Ответить | Цитировать Сообщить модератору
 Re: Условие в запросе  [new]
=)8)
Guest
Прогер_самоучка
iap
Заменил на эквивалент
На самом деле это часть собирается в программе, поэтому там именно так :)
на самом деле и в программе это лучше заменить на
(@code=-1 or code=@code) and (@f1=-1 or f1=@f1) :))
28 июн 13, 09:17    [14495458]     Ответить | Цитировать Сообщить модератору
 Re: Условие в запросе  [new]
=)8)
Guest
Павел Воронцов
Не зная схему данных трудно угадывать
+100500
28 июн 13, 09:23    [14495506]     Ответить | Цитировать Сообщить модератору
 Re: Условие в запросе  [new]
Прогер_самоучка
Member

Откуда:
Сообщений: 69031
Павел Воронцов
Прогер_самоучка
Выводил я так в select. Поэтому и говорю, что будет считать сумму сразу всех чеков.
Было вот так с добавлением having
Не зная схему данных трудно угадывать, но скорей всего Вам нужно что-то типа
select 
  b.base as [Филиал], 
  sum(op1.chks) as [Чеки] 
from (select docid
             , goodsid
             , count(distinct smid) as chks
             , sum(op.Quantity*op.Price) as summ
from op
group by docid
             , goodsid) op1
  inner join d on     op1.docid = d.id 
  inner join b on     d.bid = b.id 
  inner join w on     op1.goodsid = w.code 
where
  (
    b.id in (16,6,106,24,103,36,91,40,25)
  ) and
  (d.doctype = 6) and
  (d.docdate >= convert(datetime, '2013-06-01 00:00:00', 102)) and
  (d.docdate <= convert(datetime, '2013.06.30 23:59:59', 102)) and code between isnull(nullif(-1,-1),-2147483648)
   and isnull(nullif(-1,-1),2147483647) and f1 between isnull(nullif(-1,-1),-2147483648) and isnull(nullif(-1,-1),2147483647) 
   group by 
  b.base
  having sum(op1.summ) between 8000 and 10000


Очень даже похоже. Только не пойму, почему ничего не возвращает. Внутренний запрос отрабатывает. А по внешнему почему-то нет.

З.Ы. Под схемой данных вы подразумеваете структуры таблиц ?
28 июн 13, 10:19    [14495925]     Ответить | Цитировать Сообщить модератору
 Re: Условие в запросе  [new]
Прогер_самоучка
Member

Откуда:
Сообщений: 69031
Прогер_самоучка
Очень даже похоже. Только не пойму, почему ничего не возвращает. Внутренний запрос отрабатывает. А по внешнему почему-то нет.

Разобрался вроде бы. Нужно было в конце в группировке указать колонку chks по которой группировка chks
28 июн 13, 10:24    [14495943]     Ответить | Цитировать Сообщить модератору
 Re: Условие в запросе  [new]
Прогер_самоучка
Member

Откуда:
Сообщений: 69031
Доброго времени суток.
Есть запрос, в котором есть условие
where code between isnull(nullif(-1,-1),-2147483648) and isnull(nullif(-1,-1),2147483647) and
 f1 between isnull(nullif(-1,-1),-2147483648) and isnull(nullif(-1,-1),2147483647)

Раньше этот запрос отрабатывал нормально. Сейчас выскакивает ошибка:

Ошибка арифметического переполнения для типа данных smallint, значение = -2147483648

Но, поля Code и F1 в базе имеют тип int. раньше стоял ms sql server 2000.
Сейчас:
Microsoft SQL Server 2008 R2 (SP2) - 10.50.4263.0 (X64) 	
	Aug 23 2012 15:56:56 
	Copyright (c) Microsoft Corporation
	Enterprise Edition (64-bit) on Windows NT 6.0 <X64> (Build 6002: Service Pack 2)

Хотелось бы прояснения ситуации.
Заранее благодарю за ответы.
17 июл 13, 14:05    [14578109]     Ответить | Цитировать Сообщить модератору
 Re: Условие в запросе  [new]
капец полный
Guest
Прогер_самоучка,

тип полей тут вообще ни при чем,
любое из этох двух вызовет ту же ошибку:
select isnull(nullif(-1,-1),-2147483648)
select isnull(nullif(-1,-1),2147483647)


но ответьте плиз, откуда такой огород, почему не подходит
where code = -1 and f1 = -1
17 июл 13, 14:27    [14578243]     Ответить | Цитировать Сообщить модератору
 Re: Условие в запросе  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
капец полный,

вроде, выше говорилось, что это частный случай скрипта, генерирующегося автоматически
17 июл 13, 14:31    [14578275]     Ответить | Цитировать Сообщить модератору
 Re: Условие в запросе  [new]
=)8)
Guest
а тип параметра какой? Скорее всего, что-то вроде этого:
declare @code smallint=-1
...
select ...
where ...
   and code between isnull(nullif(@code,-1),-2147483648) and isnull(nullif(@code,-1),2147483647)
...
исправьте тип на int - ошибка уйдет
17 июл 13, 14:31    [14578278]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить