Все технические форумы на одном сайте Удобный поиск информации с популярных форумов в одном месте
Вопрос: при агрегации по датам выходят только NULL

Create table final1
(
product_id int,
shop_code nvarchar(20),
doc_date datetime,
diff2 int,
diff1 int,
BASEITLOG int,
base int,
TotalSum int
)
insert into final1 values 

(11628,'00664НСК','2015-01-01 00:00:00.000',0,208,318,318,526),
(11628,'00664НСК','2015-02-01 00:00:00.000',24,290,345,369,659),
(11628,'00664НСК','2015-03-01 00:00:00.000',12,0,503,515,515),
(11628,'00664НСК','2015-04-01 00:00:00.000',0,273,264,264,537),
(11628,'00664НСК','2015-05-01 00:00:00.000',0,195,266,266,461),
(11628,'00664НСК','2015-06-01 00:00:00.000',0,0,265,265,265),
(11628,'00664НСК','2015-07-01 00:00:00.000',482,0,231,713,713),
(11628,'00664НСК','2015-08-01 00:00:00.000',182,0,333,515,515),
(11628,'00664НСК','2015-09-01 00:00:00.000',287,0,376,663,663),
(11628,'00664НСК','2015-10-01 00:00:00.000',180,0,232,412,412),
(11628,'00664НСК','2015-11-01 00:00:00.000',0,0,197,197,197),
(11628,'00664НСК','2015-12-01 00:00:00.000',596,0,952,1548,1548),
(11628,'00664НСК','2016-01-01 00:00:00.000',0,0,375,375,375),
(11628,'00664НСК','2016-02-01 00:00:00.000',256,164,252,508,672),
(11628,'00664НСК','2016-03-01 00:00:00.000',0,0,267,267,267),
(11628,'00664НСК','2016-04-01 00:00:00.000',0,0,176,176,176),
(11628,'00664НСК','2016-05-01 00:00:00.000',0,0,181,181,181),
(11628,'00664НСК','2016-06-01 00:00:00.000',0,0,236,236,236),
(11628,'00664НСК','2016-07-01 00:00:00.000',16,455,208,224,679),
(11628,'00664НСК','2016-08-01 00:00:00.000',0,0,185,185,185),
(11628,'00664НСК','2016-09-01 00:00:00.000',0,0,196,196,196),
(11628,'00664НСК','2016-10-01 00:00:00.000',0,0,201,201,201),
(11628,'00664НСК','2016-11-01 00:00:00.000',0,454,207,207,661),
(11628,'00664НСК','2016-12-01 00:00:00.000',0,0,275,275,275),
(11628,'00664НСК','2017-01-01 00:00:00.000',0,212,116,116,328),
(11628,'00664НСК','2017-02-01 00:00:00.000',0,170,125,125,295),
(11628,'00664НСК','2017-03-01 00:00:00.000',0,0,242,242,242),
(11628,'00664НСК','2017-04-01 00:00:00.000',0,0,136,136,136),
(11628,'00664НСК','2017-05-01 00:00:00.000',0,0,193,193,193),
(11628,'00664НСК','2017-06-01 00:00:00.000',251,0,219,470,470),
(11628,'00664НСК','2017-07-01 00:00:00.000',0,0,183,183,183),
(11628,'00664НСК','2017-08-01 00:00:00.000',0,11,219,219,230),
(11628,'00664НСК','2017-09-01 00:00:00.000',0,204,194,194,398),
(11628,'00664НСК','2017-10-01 00:00:00.000',0,81,204,204,285),
(11628,'00664НСК','2017-11-01 00:00:00.000',0,60,191,191,251),
(11628,'00664НСК','2017-12-01 00:00:00.000',16,207,251,267,474),
(11628,'00664НСК','2018-01-01 00:00:00.000',0,0,148,148,148),
(11628,'00664НСК','2018-02-01 00:00:00.000',0,0,164,164,164),
(11628,'00664НСК','2018-03-01 00:00:00.000',0,0,277,277,277),
(11628,'00664НСК','2018-04-01 00:00:00.000',0,0,137,137,137),
(11628,'00664НСК','2018-05-01 00:00:00.000',0,274,194,194,468),
(11628,'00664НСК','2018-06-01 00:00:00.000',12,30,184,196,226),
(11628,'00664НСК','2018-07-01 00:00:00.000',0,0,134,134,134),
(11628,'00664НСК','2018-08-01 00:00:00.000',0,32,116,116,148),
(11628,'00664НСК','2018-09-01 00:00:00.000',0,115,117,117,232)

;With CTE
AS
(
SELECT *,YEAR(doc_date) AS DocYr,DATENAME(mm,doc_date) AS DocMnth
FROM final1
)
SELECT variable,product_id,shop_code,DocYr AS [Year],
MAX(CASE WHEN DocMnth = 'January' THEN val END) AS Jan,
MAX(CASE WHEN DocMnth = 'February' THEN val END) AS Feb,
MAX(CASE WHEN DocMnth = 'March' THEN val END) AS Mar,
MAX(CASE WHEN DocMnth = 'April' THEN val END) AS Apr,
MAX(CASE WHEN DocMnth = 'May' THEN val END) AS May,
MAX(CASE WHEN DocMnth = 'June' THEN val END) AS Jun,
MAX(CASE WHEN DocMnth = 'July' THEN val END) AS Jul,
MAX(CASE WHEN DocMnth = 'August' THEN val END) AS Aug,
MAX(CASE WHEN DocMnth = 'September' THEN val END) AS Sep,
MAX(CASE WHEN DocMnth = 'October' THEN val END) AS Oct,
MAX(CASE WHEN DocMnth = 'November' THEN val END) AS Nov,
MAX(CASE WHEN DocMnth = 'December' THEN val END) AS [Dec]
FROM
(
SELECT product_id ,
shop_code ,
diff2 ,
diff1 ,
BASEITLOG ,
base ,
TotalSum ,DocYr,DocMnth
FROM CTE
)c
UNPIVOT(val FOR  variable IN ([diff2],[diff1],[BASEITLOG],[base],[TotalSum]))u
GROUP BY variable,product_id,shop_code,DocYr



у меня получаются нулы
variable product_id shop_code Year Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
base 11628 00664НСК 2015 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL

Но это неправильный расчет, там должны быть агрегированные значения.Как сделать правильно?
Ответ: Kontox,

определить номер месяца числом религия не позволяет, что ли? Вам же пример написали.
Вопрос: Столбец NOT NULL

Здравствуйте!
Добавил столбец в имеющуюся таблицу.
Но, этот столбец должен быть NOT NULL - изменить не дает... только NULL

Как быть?
Ответ: А почему нельзя поле добавить сразу с дефолтным констрейнтом?
Вопрос: Использование CASE в WHERE при значении NULL

Добрый день
К какой категории языка относится нижеизложенное ответить затрудняюсь, но скорее всего ближе к MSSQL. Специализированная софтина с возможностью выполнения запросов.

Имеется такое условие
select * from table
where LastTime like (case when @variable='Не удалось определить дату' then NULL else  @variable+'%' end)

т.е. пользователь может ввести "Не удалось определить дату", и тогда надо найти те записи, где LastTime is NULL, если же пользователь ввел какую-то дату, то искать по этой (введенной) дате.
Как выводить данные в зависимости от введенных значений?
Ответ:
select * from table
where isnull(LastTime, '19000101') like (case when @variable='Не удалось определить дату' then '19000101' else  @variable+'%' end)
Вопрос: Run time error 94 invalid use of null access

Помогите пожалуйста!!!!
Вот событие кнопки при нажатии:
Код Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
Private Sub cmdOpenReport_Click()
Dim S As String, _
i As Byte
'For i = 1 To 11
S = " "
If Me("cbx4") Then
S = S & ",[Договоры аренды МИ].[Тип помещения]"
End If
If Me("cbx5") Then
S = S & ",[Договоры аренды МИ].[Описание помещения]"
End If
If Me("cbx6") Then
S = S & ",[Договоры аренды МИ].[АП в год]"
End If
If Me("cbx7") Then
S = S & ",[Договоры аренды МИ].[АП в месяц]"
End If
If Me("cbx8") Then
S = S & ",[Договоры аренды МИ].[Номер договора]"
End If
If Me("cbx9") Then
S = S & ",[Договоры аренды МИ].[Дата договора]"
End If
If Me("cbx10") Then
S = S & ",[Договоры аренды МИ].[Срок окончания договора]"
End If
 
CurrentDb.QueryDefs!Query01_Query.SQL = "SELECT [Договоры аренды МИ].[№],[Договоры аренды МИ].[Адрес объекта аренды],[Договоры аренды МИ].[Арендатор],[Договоры аренды МИ].[Площадь] " & S & " FROM [Договоры аренды МИ] WHERE [Договоры аренды МИ].[Дата расторжения] IS NULL;"
DoCmd.OpenReport "Report02_Report", acViewPreview
End Sub
Где здесь ошибка?? Ситуация такая - Если открыть форму и активировать все chebox'ы и нажать на кнопку, то все ок, и потом можно снимать флажки, но все, без разницы... То все также работает.
Но если открыть форму и не активировать ни одного checkbox'а или хотя бы один оставить без флажка, то появляется эта ошибка...
Подскажите, что не так)))
Ответ: Урааааааааааааааааааааа!!! Помогло- - - ->
If (Me.cbx4) Then
Вопрос: Проектирование: есть ли смысл разрешать null-значения для "бизнес-данных"?

База, в в ней таблички. Каждая табличка имеет суррогатный ключ типа Int64.
Таблички связаны между собой с помощью FK - ограничений. Каждое поле, ссылающееся по FK на другую табличку, может быть как "nullable", так и "not null", в зависимости от особенностей FK - связи. Тут удобство null-ов не вызывает сомнений.
С полями, реализующими FK-связи, вопросов нет.
...
А еще есть поля, несущие уже "кондовую" смысловую нагрузку: Фамилия, Стоимость, Адрес...
Какой смысл разрешать для таких полей значение null?

Ну, можно придумать. Например, поле "Дата начала строительство". Пока оно null, строительство и не началось. Но ведь можно для этого задействовать какую-либо "волшебную константу", какой-нибудь
cast(0 as date)
...

Для строк использовать значение "пустая строка", для чисел - "0".

Null, конечно, сам по себе является такой "волшебной константой". Но ведь значение 0 (или "пустая строка") можно использовать в запросах наравне с остальными значениями, а с null-ами приходится кочевряжиться!

Вот и вопрос: есть ли смысл для "бизнес" - значений использовать типы с ограничениями
not null & (devault value = 0|'')
?

Не создаст ли сие каких-либо неудобств в дальнейшем?
Ответ: Юзер 01,

skyANA все точно описал.
При проектировании базы Вы на 100% не можете заложить все нужные константы на все случаи жизни для всех разных атрибутов всех разных сущностей.
Может конечно и сможете, но это потребует умопомрачительной работы, анализа и знания данных предметной области, причем с учетом перспективы будущего.
Т.е. есть большой шанс нарваться на то, что Ваша константа в один прекрасный момент вдруг станет не пустым значением для предметной области и бизнес-логики, со всеми вытекающими последствиями для системы.
Null умные люди специально придумали именно для того, чтобы указывать что значение неизвестно. Это значение ни с чем не пересечется, оно не равно никакому другому значению в предметной области.

Это как 0 - специальное число, которое до поры до времени числом не считали. Пока есть что считать, ноль нас мало интересует. Но чтобы обозначит как-то, что считать нечего, придумали 0. А в математ теориях это уже полноправное число и без него уже никак.
Вопрос: bulk-insert'ы при контроле поля на not-null: benchmark для 2 млн строк в 2.5 SC vs 3.0 SC

hi all.

Понадобилось как-то затащить в таблицу оч-чень много строк из базы-источника. DDL таблиц полностью совпадает, перенос идёт с помощью IB DataPump.
Ясен пень, что если убрать индексы с таблицы-приёмника, то скорость увеличится. Но захотелось также выкинуть (временно) все check'и на ней - "а вдруг взлетит еще быстрее ?".

Результат для 2.5 слегка удивил.
Если not-null задано вот так:
recreate table tgt1(id int not null); -- field-defined not-null constraint
или вот так:
create domain dm_id_check_nn int check(value is not null);
recreate table tgt4(id dm_id_check_nn); -- nullable domain + EXPLICIT constraint on domain
или еще вот так:
create domain dm_id_not_null int not null;
recreate table tgt5(id dm_id_not_null);
insert into tgt5 select * from src; -- NOT-null domain constraint
-- то скорость инсертов от наличия/отсутствия этих констрейнтов практически НЕ меняется.

Если же not-null обеспечивается в явном виде:
recreate table tgt2(id int, constraint tgt2_chk_id_nn check(id is not null));
insert into tgt2 select * from src; -- EXPLICIT not-null constraint on field
или вообще по-дэбильному:
recreate table tgt3(id int); create trigger tgt3_biu for tgt3 active before insert or update as begin if (new.id is null) then exception exc_id_nn; end
insert into tgt3 select * from src; -- trigger checking
-- то скорость инсертов от удаления этих перлов растёт (в 2.5) примерно в 3 раза.

Почему так сильно проигрывают предпоследний и последний варианты ? (вариант через триггер хотя и выглядит "не комильфо", однако все check'и ведь тоже внутрях реализованы как триггера! Поэтому столь большая разница как-то настораживает).

#######################

Результат для 3.0 также породил душевные терзания.
В нём явный проигрыш в скорости инсертов наблюдается там же, где и для 2.5. Однако статистика вставок проигрывает во всех остальных случаях проигрывает примерно в 1.5 раза. ДЕ мне как-то говорил, что 3.0 будет выигрывать у 2.5 только при многопользовательской нагрузке, а в моно-коннекте выигрыш совсем не гарантирован. Однако дифферент 1.5 раза - как-то уж очень сильно... :( Получается, миграцию действительно больших данных вообще лучше в 2.5 делать, а затем b/r ?

Вот тест:
+
-- init DDL:
recreate table src(id int);
commit;
set term ^;
execute block as
declare n int = 2000000;
begin
while (n>0) do insert into src(id) values(:n) returning :n-1 into n;
end
^
set term ;^
commit;

-- test:

set bail on;
recreate table tgt0(id int);
recreate table tgt1(id int not null);
recreate table tgt2(id int, constraint tgt2_chk_id_nn check(id is not null));
recreate table tgt3(id int);
recreate table tgt4(id int);
recreate table tgt5(id int);
commit;

set term ^;
execute block as
begin
begin
execute statement 'drop domain dm_id_check_nn';
when any do begin end
end
begin
execute statement 'drop domain dm_id_not_null';
when any do begin end
end
begin
execute statement 'drop exception exc_id_nn';
when any do begin end
end
end
^
set term ;^
commit;
create domain dm_id_check_nn int check(value is not null);
create domain dm_id_not_null int not null;
commit;

recreate table tgt4(id dm_id_check_nn);
recreate table tgt5(id dm_id_not_null);

create exception exc_id_nn 'id is null';
commit;

set term ^;
create trigger tgt3_biu for tgt3 active before insert or update as
begin
if (new.id is null) then exception exc_id_nn;
end
^
set term ;^
commit;

set stat on;
set count on;
set echo on;

insert into tgt0 select * from src; -- no conctraints
insert into tgt1 select * from src; -- field-defined constraint
insert into tgt2 select * from src; -- EXPLICIT not-null constraint on field
insert into tgt3 select * from src; -- trigger checking
insert into tgt4 select * from src; -- domain, EXPLICIT constraint
insert into tgt5 select * from src; -- domain-defined not-null constraint
set echo off;
set stat off;
commit;

А вот сводный результат по пяти запускам на каждом ФБ (приведены данные, начиная со второго прогона в каждом случае, дабы убрать влияние затрат на рост файла БД):

0.
recreate table tgt0(id int);
insert into tgt0 select * from src; -- no conctraints
run-1run-2run-3run-4run-5
elapsed_ms, FB 3.0 SC51075083508350835121
elapsed_ms, FB 2.5 SC32883297330332843286
ratio: 3.0 / 2.5:1,551,541,541,551,56


1.
recreate table tgt1(id int not null);
insert into tgt1 select * from src; -- field-defined not-null constraint
run-1run-2run-3run-4run-5
elapsed_ms, FB 3.0 SC53105303528653025307
elapsed_ms, FB 2.5 SC35493546353135133500
ratio: 3.0 / 2.5:1,501,501,501,511,52


2.
recreate table tgt2(id int, constraint tgt2_chk_id_nn check(id is not null));
insert into tgt2 select * from src; -- EXPLICIT not-null constraint on field
run-1run-2run-3run-4run-5
elapsed_ms, FB 3.0 SC74807474748574818199
elapsed_ms, FB 2.5 SC1010610125100911009510098
ratio: 3.0 / 2.5:0,740,740,740,740,81


3.
recreate table tgt3(id int); 
create trigger tgt3_biu for tgt3 ... as begin if (new.id is null) then exception exc_id_nn; end
insert into tgt3 select * from src; -- trigger checking
run-1run-2run-3run-4run-5
elapsed_ms, FB 3.0 SC89358907958989098981
elapsed_ms, FB 2.5 SC1194812103114961244911990
ratio: 3.0 / 2.5:0,750,740,830,720,75


4.
create domain dm_id_check_nn int check(value is not null);
recreate table tgt4(id dm_id_check_nn);
insert into tgt4 select * from src; -- domain, EXPLICIT constraint
run-1run-2run-3run-4run-5
elapsed_ms, FB 3.0 SC53625317531453105301
elapsed_ms, FB 2.5 SC35383518351635373523
ratio: 3.0 / 2.5:1,521,511,511,501,50


5.
create domain dm_id_not_null int not null;
recreate table tgt5(id dm_id_not_null);
insert into tgt5 select * from src; -- domain-defined not-null constraint
run-1run-2run-3run-4run-5
elapsed_ms, FB 3.0 SC55995329532853255323
elapsed_ms, FB 2.5 SC39983549350535193497
ratio: 3.0 / 2.5:1,401,501,521,511,52


PS.
Версии ФБ:
LI-V2.5.5.26910
LI-V3.0.0.32008

База в обоих случаях: page_size = 4K, fw = OFF.
Кол-во буферов в обоих инстансах ФБ: 512, арх-ра: SuperClassic.
Ответ:
Симонов Денис
в твоём тесте получается, что в трёшке триггеры работают быстрее, а движок медленнее. Странно это...
ну, вот так вот... прогони у себя, получишь, скорее всего тоже самое.

Симонов Денис
И ещё у тебя тест не совсем чистый. Где гарантия что медленней именно insert, а не select * from src
Сколько там хоть записей то и как они распределены?
затраты на select * from src - это по-любасу постоянная величина. И в стартовом посте всё видно, под спойлером: таблица содержит только числовое поле ID, от 1 до 2'000'000. Индексов нигде нету.
Вопрос: увеличить даты из поля дата на основании поля тип и вывести в третье поле

В поле тип может быть несколько вариантов и в зависимости от значения увеличивать дату.
Если тип = 1, увеличиваем на 10 дней, если тип = 2, то на 10 дней и т.п.

Курение интернетов навело на мысль использовать выражение с DLOOKUP.
Но что-то не задалось. Решил попробовать просто вывести дату, например, только для тип = 1.
SQL
1
DLookUp("Дата";"Таблица1";"тип = 1")
Дату он мне, конечно показал, но для всех записей и для всех одинаковую.
В общем, я понял, что не достаточно хорошо понимаю механизм работы..

Изначально пробовал в VBA реализовать, но вышла та же бяка.

Для примера набросал табличку с запросом.
Ответ: Немного подшаманил, а то не считал он даты. Посмотрите, пожалуйста, это годиться для рабочего варианта?
Обработку ошибок добавлю, конечно.

Мой вариант - запрос4
Спасибо.
Вопрос: хотя бы один из переменных = null

подскажите плиз есть ли одной функцией проверка на равенство одного из множеств NULL'ю
нужен аналог:
5 in (1,4,5,6) равен t

только надо что бы было так:
???(1,4,null,6) равнялся бы t
Ответ:
vsl
Legushka,

create or replace function is_not_distinct_from(a integer,b integer) returns boolean as $$
    select a is not distinct from b as result;
$$ language sql cost 1;
create operator === (leftarg=integer,rightarg=integer,procedure=is_not_distinct_from);


select null === any(array[5,6,7,null,8])

!
откуда мораль -- "is not distinct from" и "is distinct from" -- не операторы, а бред сивой кобылы.
если бы "IS" был оператором со значением "is not distinct from" а "IS NOT" -- оператором со значением "is distinct from", то всё было бы весьма стройно. а не наследовало бы ублюдочному стандарту, что "IS NULL" -- однопозиционный оператор. а не частный случай использования оператора "a IS b". появилась бы утраченная симметрия.
а если б их еще и по индексам... -- цены б не было.
а главное -- старый код бы не пострадал. почти :]
а то "is not distinct from" -- казалось бы именно оператор проверки совпадения с узлом индекса -- ан хрен, изволь руками расписывать вариации. иначе не подхватит.


то же с симметрией any() -- в 9.4. any и all допускались только у левого операнда, как его модификаторы. (это по поводу контры).
Вопрос: Выборка за разные даты одним запросом

Всем привет.

Есть (на пример) 2 таблицы
1) ID | Товар | Тип товара
2)ID товара | Дата поступления

Мне нужно сделать запросом так, что бы получилось

Тип товара | Кол-во поступившего товара с 1-7 число | Кол-во поступившего товара с 8-14 число | Кол-во поступившего товара с 14-21 число

Как подсчитать кол-во я знаю, а вот как сделать так, что бы одним запросом можно было бы подсчитать кол-во поступившего товара (в разных столбцах за разные даты). Вижу только один выход - через временные таблицы, но может есть выход поудобнее?
Ответ: Есть выход поудобнее.
(У Вас 14-е число попало в два столбца)
Используйте оператор CASE.
T-SQL
1
2
3
4
5
6
select ТипТовара
, SUM (CASE WHEN day(Дата поступления) between 1 and 7 THEN Количество ELSE 0 END) 
, SUM (CASE WHEN day(Дата поступления) between 8 and 14 THEN Количество ELSE 0 END) 
, SUM (CASE WHEN day(Дата поступления) between 15 and 21 THEN Количество ELSE 0 END) 
from Товары inner join Поступления on (Товары.ID=Поступления.IDТовара)
group by ТипТовара
Вопрос: Добавление ограничение NOT NULL к существующему типу поля

Всем привет!

Как изменить свойство поля с
start_km integer на start_km integer not null?

Данная штука увы (естественно) не прокатывает:

alter table xx_apr_speed_tr alter start_km type integer not null;


Вот это выдал FlameRobin при установке галочки <хочу not null>:

(*)
UPDATE XX_APR_SPEED_TR 
SET START_KM = ' ' 
WHERE START_KM IS NULL;
UPDATE RDB$RELATION_FIELDS SET RDB$NULL_FLAG = 1
WHERE RDB$FIELD_NAME = 'START_KM' AND RDB$RELATION_NAME = 'XX_APR_SPEED_TR';


Правильно ли я понимаю, что SET START_KM = ' ' заменяет уже существующие значения NULL на значения, которое мы укажем в ' '? А затем идет условие невозможности значения NULL в столбце START_KM?

Есть ли смысл - заморачиваться с (*), может просто удалить поле и заново его добавить?
Ответ:
guly2808

Данная штука увы (естественно) не прокатывает:

alter table xx_apr_speed_tr alter start_km type integer not null;



правильный способ появился только в Firebird 3.0

ALTER TABLE tablename
ALTER [COLUMN] colname [SET | DROP] NOT NULL