У меня есть данные временных рядов с меткой времени ТЕКСТ в формате DD.MM.YYYY HH:mm:ss.sss
(.sss
= мс).
Я извлекаю каждый компонент из поля метки времени ТЕКСТ и составляю метку времени в формате ISO как YYYY-MM-DD HH:mm:ss.sss
.
Я прочитал документацию по функции strftime
, но следующее не работает:
CREATE TABLE tickdata (
DateTime TEXT, -- source format = "DD.MM.YYYY HH:mm:ss.sss"
class TEXT,
category TEXT,
upper INT,
lower INT,
diff INT GENERATED ALWAYS AS (upper - lower) STORED,
gen_year INT GENERATED ALWAYS AS (SUBSTRING(DateTime, 7, 4)) STORED,
gen_month INT GENERATED ALWAYS AS (SUBSTRING(DateTime, 4, 2)) STORED,
gen_day INT GENERATED ALWAYS AS (SUBSTRING(DateTime, 1, 2)) STORED,
gen_wkd INT GENERATED ALWAYS AS CAST(strftime('%w',DateTime) AS INT) STORED, -- syntax error
-- gen_wkd INT GENERATED ALWAYS AS strftime('%w',DateTime) STORED, -- also syntax error
-- gen_wkd CAST(strftime('%w',DateTime) AS INT) GENERATED ALWAYS STORED, -- also syntax error
gen_hr INT GENERATED ALWAYS AS (SUBSTRING(DateTime, 12, 2)) STORED,
gen_min INT GENERATED ALWAYS AS (SUBSTRING(DateTime, 15, 2)) STORED,
gen_sec INT GENERATED ALWAYS AS (SUBSTRING(DateTime, 18, 2)) STORED,
gen_ms INT GENERATED ALWAYS AS (SUBSTRING(DateTime, 21, 3)) STORED,
gen_ISODate TEXT GENERATED ALWAYS AS (
FORMAT('%04d', gen_year) || '-' ||
FORMAT('%02d', gen_month) || '-' ||
FORMAT('%02d', gen_day) || ' ' ||
FORMAT('%02d', gen_hr) || ':' ||
FORMAT('%02d', gen_min) || ':' ||
FORMAT('%02d', gen_sec) || '.' ||
FORMAT('%03d', gen_ms) -- format = "YYYY-MM-DD HH:mm:ss.sss"
) STORED
);
Как создать вычисляемый столбец, в котором будет храниться день недели, в который попадает каждая временная метка строки?
Как и в комментарии, вам нужно заключить круглые скобки.
Кроме того, вы передаете неправильный аргумент.
gen_wkd INT GENERATED ALWAYS AS (strftime('%w', gen_ISODate)) STORED,
Множественный конкат format
+ может быть всего лишь одним вызовом, и, судя по выводу explain
, такой вывод может быть более эффективным:
printf('%04d-%02d-%02d %02d:%02d:%02d.%03d',
gen_year, gen_month, gen_day,
gen_hr, gen_min, gen_sec, gen_ms)
(Если вы имеете в виду ISO 8601, разве пробел не должен быть T
?)
Я полагаю, что вы технически правы, говоря, что пробел между date
и time
должен быть T
, если это соответствует ISO 8601... главное для меня - правильная возможность сортировки по временной метке, поэтому в данном случае это не имеет значения. разница, пока она последовательна. Но я принимаю вашу точку зрения...
Можете ли вы дать полный синтаксис строки для printf('%04d-%02d-%02d %02d:%02d:%02d.%03d', gen_year, gen_month, gen_day, gen_hr, gen_min, gen_sec, gen_ms)
?
Не уверен, что вы имеете в виду. gen_ISODate TEXT GENERATED ALWAYS AS ( printf(...) ) STORED
? (Я понимаю, что printf теперь просто псевдоним формата, но, похоже, это произошло после моей версии (3.37.2), о которой я не знаю format
Тестирование показывает, что этот код SQL с printf()
работает: CREATE TABLE data (DateTime TEXT,g_year INT GENERATED ALWAYS AS (SUBSTRING(DateTime,7,4)) STORED,g_month INT GENERATED ALWAYS AS (SUBSTRING(DateTime,4,2)) STORED,g_day INT GENERATED ALWAYS AS (SUBSTRING(DateTime,1,2)) STORED,g_hr INT GENERATED ALWAYS AS (SUBSTRING(DateTime,12,2)) STORED,g_min INT GENERATED ALWAYS AS (SUBSTRING(DateTime,15,2)) STORED,g_sec INT GENERATED ALWAYS AS (SUBSTRING(DateTime,18,2)) STORED,g_ISODate TEXT GENERATED ALWAYS AS (printf('%04d-%02d-%02d %02d:%02d:%02d',g_year,g_month,g_day,g_hr,g_min,g_sec)) STORED);
Спасибо, вы были правы, я использовал неправильный столбец ввода. День недели теперь работает, а точка по-прежнему нет. Прочитаю документ еще раз...
Синтаксические ошибки возникают из-за того, что производящая функция должна быть в круглых скобках, как в
INT GENERATED ALWAYS AS (strftime...)
.