![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как заставить SUM обрабатывать NULL [MSSQL]
Ольга © (2006-09-22 10:51:00)Есть 2 таблицы - справочник объектов и данные по объектам.
Нужно посчитать суммы данных по объектам и датам, но так, чтобы сумма считалась только тогда, когда есть данные по всем объектам за дату, иначе сумма=NULL
Мой запрос выдает некорректные суммы (по тем данным, что есть, NULL игнорируется):
SELECT id_obj, dt, SUM(b.Value)
FROM cls_objects a LEFT OUTER JOIN obj_data b ON a.id_obj=b.id_obj
GROUP BY id_obj, dt
sniknik (2006-09-22 11:27:00) [21]SELECT CASE Sum(isNull(f-f,1)) WHEN 0 THEN Sum(f) ELSE Null END FROM Table1
Ольга (2006-09-22 11:27:00) [22]
> [9]
Оказывается конструкция (раньше я ее использовала) SUM(IsNull(b.Value, 0)) вообще бессмысленная, т.к. = SUM(b.Value)
> [11]
Да, хотелось бы попроще...
ЮЮ (2006-09-22 11:27:00) [23]Если в [8] я правильно понял, то
DECLARE @ObjectsCnt int
SET @ObjectsCnt = SELECT COUNT(*) FROM cls_objects
SELECT
id_obj,
CASE Cnt WHEN @ObjectsCnt THEN SumValue ELSE NULL END MySumValue
FROM (
SELECT
a.id_obj, dt,
SUM(b.Value) SumValue, COUNT(DISTINCT b.id_obj) Cnt
FROM
cls_objects a
LEFT OUTER JOIN obj_data b ON a.id_obj=b.id_obj
GROUP BY id_obj, dt
) gr
Sergey13 (2006-09-22 11:26:00) [24]> [6] Val © (22.09.06 11:10)
> зачем тут 0 дефолтный тогда..
Я всегда так делать стараюсь. Конкретно тут это пофиг, а вот на SUM(Field1*Field2) можно здорово огрести.
Stanislav (2006-09-22 11:24:00) [25]ВОТ ТАК:
Select CASE WHEN SUM(Case WHEN N is NUll then 1 else 0 end)>0 THEN NULL ELSE SUM(N)END FROM
(SELECT 1 as N
UNION ALL
SELECT 1
UNION ALL
SELECT 1
UNION ALL
SELECT 3) as Q
Stanislav (2006-09-22 11:22:00) [26]Вобще это можно без вложеных запросов сделать.
Johnmen (2006-09-22 11:20:00) [27]
> исли встретился хоть один NULL в составляющих, то вся сумма
> = NULL
Не может быть! :)
Stanislav (2006-09-22 11:19:00) [28]Можно так
Select (Case when c>0 then NULL ELSE A END) as SUMMA FROM (
Select SUM (ALL N) as A, c=SUM(Case WHEN N is NUll then 1 else 0 end) FROM
(SELECT 1 as N
UNION ALL
SELECT 1
UNION ALL
SELECT 1
UNION ALL
SELECT NULL) as Q) as Q2
Ольга (2006-09-22 11:15:00) [29]
> [6]
Эт не то. Есть в T-SQL аналог ISNULL, но она не умеет делать, как я хочу -
исли встретился хоть один NULL в составляющих, то вся сумма = NULL
Ega23 (2006-09-22 11:15:00) [30]Использовать IsNull:
SELECT id_obj, dt, SUM( IsNull(b.Value, 0))
FROM cls_objects a LEFT OUTER JOIN obj_data b ON a.id_obj=b.id_obj
GROUP BY id_obj, dt
ЮЮ (2006-09-22 11:13:00) [31]
> в вопрос я тоже до конца не врулил :(
Не за все даты нужна численная сумма, а лишь за те, где сумма не NULL для ВСЕХ объектов, иначе считать её NULL, даже если это и не так.
Если я правильно понял
Ольга (2006-09-22 11:11:00) [32]
> [5]
Именно так. Как это сделать, используя процедуру т.п., понятно.
Хотелось бы запросом, если возможно.
Val (2006-09-22 11:10:00) [33]>[2] Sergey13 © (22.09.06 10:56)
да в mssql вроде есть аналог nvl - coalesce что-ли..зачем тут 0 дефолтный тогда..
в вопрос я тоже до конца не врулил :(
Stanislav (2006-09-22 11:04:00) [34]Я правильно понял?
POLE
3
5
7
Null
SUM(POLE)=NULL
ЮЮ (2006-09-22 11:04:00) [35]1) Такой запрос вообще не выполнится, ибо поле id_obj есть в двух таблицах
2) NULL в таком запросе никак не может влиять на сумму, ибо в неё не входит
Нужно посчитать суммы данных по объектам и датам, но так, чтобы сумма считалась только тогда, когда есть данные по всем объектам за дату, иначе сумма=NULL
Тогда и запрос надо писать так, а не как придется
Johnmen (2006-09-22 10:57:00) [36]
> NULL игнорируется
А должен складываться? :)
Или я что-то не понял вопроса...
Sergey13 (2006-09-22 10:56:00) [37]По тем полям, по которым надо получать SUM желательно выставлять 0 по дефолту для избавления от NULL.
Если в запрос добавить еще и Count(*), то должны появиться и "пропавшие" записи.
Desdechado (2006-09-22 10:55:00) [38]> есть данные по всем объектам за дату
Как это определить?
> по тем данным, что есть, NULL игнорируется
Может, поставить INNER JOIN