![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Access, ADO [D7, Access, ADO]
Е. © (2006-01-14 09:39:00)Есть таблица [ОбъемРабот] с полями:
[КодЦеха] - Длинное целое
[КодРаботы] - Длинное целое
[Январь] - Одинарное с плавающей точкой
[Февраль] - Одинарное с плавающей точкой
...
[Декабрь] - Одинарное с плавающей точкой.
Месяца в таблице обозначают объем данной работы КодРаботы), выполненной данным цехом(КодЦеха) в данном месяце.
Необходимо подсчитать суммарный объем по каждой работе за год всего предприятия. Я делаю запрос:
SELECT
SUM(Январь+Февраль+...+Декабрь) AS [Объем],
КодРаботы
FROM
ОбъемРабот
GROUP BY
КодРаботы;
и получаю неправильный результат (некоторые значения равны нулю). В справке MS Access сказано, что "Функция Sum пропускает записи с полями, содержащим значения Null". Если дело в этом, то каким образом можно это обойти? Или запрос составлен неверно?
sniknik (2006-01-15 13:32:00) [1]> ...но работает почему-то только непосредственно в Access.
т.к. это функция самого приложения (Application), а не jet (он только встроенный бейсик может использовать, но не функции описаные в разных "левых" программах)
иллюстрация
unit AccessAppUnit;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, AccessXP, ComObj;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Label1: TLabel;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
TestNull: OleVariant;
public
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
TestNull:= Null;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
appAccess: _Application;
begin
appAccess:= CreateComObject(CLASS_AccessApplication) as _Application;
try
Label1.Caption:= appAccess.Nz(TestNull, 'NULL');
finally
appAccess:= nil;
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
TestNull:= 'NOT NULL';
end;
end.
Е. (2006-01-15 11:12:00) [2]Нашлась некая функция Nz в MS Access, с ней запрос выглядит "красивее и понятнее":
SELECT
SUM(Nz(Январь)+Nz(Февраль)+..+Nz(Декабрь)) AS Объем,
КодРаботы
FROM
ОбъемРабот
GROUP BY КодРаботы;
...но работает почему-то только непосредственно в Access. Если использовать через ADOQuery.Sql выдает ошибку: "Неопределенная функция 'Nz' в выражении." Почему?
sniknik (2006-01-14 13:09:00) [3]Anatoly Podgoretsky © (14.01.06 12:51) [10]
> Это не важно, даже в пределах одной записи результат будет NULL если хотя бы одно из полей NULL
так именно это я и сказал... сумма в "линейку" дает Null ...
но т.к. в [6]/[8] рассматривался второй вариант (SUM([Январь])+SUM([Февраль])+...) то тут сначала складываются "столбики" и до строки Null "дойдет" только если весь столбец из Null. (в "столбиках" Null просто пропускается)
> Только первый вариант даст нужный результат, преобразование NULL в 0
если много значений и гарантированно хоть одно поле каждого столбца проинициализировано (есть значение), то и второй вариант сработает.
p.s. ктото когото не понял...
Anatoly Podgoretsky (2006-01-14 12:51:00) [4]sniknik © (14.01.06 10:48) [6]
sniknik © (14.01.06 11:01) [8]
Это не важно, даже в пределах одной записи результат будет NULL если хотя бы одно из полей NULL
Только первый вариант даст нужный результат, преобразование NULL в 0
Е. (14.01.06 10:37) [4]
А ты столбиком запиши, будет и красиво и понятно.
Е. (2006-01-14 11:09:00) [5]
> sniknik © (14.01.06 11:01) [8]
> а понял. у тебя же там группировка, т.е. SUM-мируются небольшие
> группы значений, и наверное попадает что вся группа по какомуто
> месяцу из значений Null ... тогда и вся сумма Null и сложение
> сумм где есть хоть одна с Null даст Null ...
>
> "неправильный результат" это пропуски да? (пустые значения).
> если да то все верно, и второй тебе не подойдет.
Да именно так. Еще раз спасибо.
sniknik (2006-01-14 11:01:00) [6]а понял. у тебя же там группировка, т.е. SUM-мируются небольшие группы значений, и наверное попадает что вся группа по какомуто месяцу из значений Null ... тогда и вся сумма Null и сложение сумм где есть хоть одна с Null даст Null ...
"неправильный результат" это пропуски да? (пустые значения). если да то все верно, и второй тебе не подойдет.
sniknik (2006-01-14 10:51:00) [7]> Интересно, функция SUM везде так странно работает или только в MS Access?
это не SUM это правила Null -> 1 + Null = Null (и вообще любое число + Null)
будет везде аналогично, правда с исключениями... (в MSSQL например это поведение настраиваемо, по умолчанию также (на тех установках mssql что я делал))
sniknik (2006-01-14 10:48:00) [8]> Тот же результат во втором варианте.
по идее не должно
приведи второй вариант полностью, как ты его написал.
Е. (2006-01-14 10:45:00) [9]Интересно, функция SUM везде так странно работает или только в MS Access?
Е. (2006-01-14 10:37:00) [10]А вот первый вариант работает, правда несколько громоздко выглядит, но работает. Спасибо.
PS. Остается ощущение, что можно как-то упростить. Или нет?
Е. (2006-01-14 10:09:00) [11]Тот же результат во втором варианте.
Е. (2006-01-14 10:08:00) [12]Тот же результат.
sniknik (2006-01-14 09:50:00) [13]> Если дело в этом, то каким образом можно это обойти?
SUM(iif(IsNull([Январь]),0,[Январь])+...)
или
SUM([Январь])+SUM([Февраль])+...