Начало » Использование СУБД » PostgreSQL » Выполнение запроса в цикле на уровне SQL запроса (Выполнение запроса в цикле на уровне SQL запроса)
Выполнение запроса в цикле на уровне SQL запроса [сообщение #5249] |
Fri, 19 July 2024 12:16 |
qwerty5000
Сообщений: 13 Зарегистрирован: July 2024
|
Junior Member |
|
|
Доброго времени суток!
Коллеги, требуется помощь в решении задачки.
Дано:
Имеется вот такой запрос который транспонирует временной ряд в более реляционный вид (запрос упрощен и представлен для одного тега).
Запрос вытаскивает последнее значение за сутки.
На вход получаю произвольную дату на основе которой необходимо сформировать отчет за месяц, пусть будет 19.07.2024
SELECT
'Дата' AS repdate,
CASE WHEN t1.tagname = 'ASRMB.U_AVT12.FT0002.Out.Mt' THEN t1.dvalue END AS ASRMB_U_AVT12_FT0002_Out_Mt,
FROM (
SELECT case when h.recordtype = 'inner' then h.valdouble else NULL END AS dValue, h.time, n.tagname
FROM nodes_history h JOIN nodes n ON n.NodeId = h.NodeId
WHERE n.TagName = 'ASRMB.U_AVT12.FT0002.Out.Mt' AND (h.time BETWEEN '2024-07-18 00:00:00.00' AND '2024-07-18 23:59:59.00') AND h.recordtype != 'ubound' ORDER BY h.time DESC LIMIT 1) t1,
Нужно:
На уровне SQL запроса, как-то разложить дату от 19 числа по 1 число с шагом в сутки.
Поочередно подставить каждую дату в запрос и в результате получить набор значений по дням с 1 по 19 число месяца.
Буду очень признателен за любую посильную помощь, времени совсем нет, а заказчик не ждет.
Спасибо!
[Обновления: Fri, 19 July 2024 12:32] Известить модератора
|
|
|
|
|
|
|
|
|
|
|
|
|
Re: Выполнение запроса в цикле на уровне SQL запроса [сообщение #5266 является ответом на сообщение #5264] |
Fri, 19 July 2024 16:30 |
qwerty5000
Сообщений: 13 Зарегистрирован: July 2024
|
Junior Member |
|
|
BlackEric писал(а) Fri, 19 July 2024 15:26qwerty5000 писал(а) Fri, 19 July 2024 15:09BlackEric писал(а) Fri, 19 July 2024 13:37While loop. тогда в обычном цикле.
Уменьшайте значение на 1 в каждой итерации и так пока будет >=1.
а как будет выглядеть структура такого запроса, вложенный запрос крутить в цикле ? Непонятен момент когда будет склеиваться в цикле таблица )
Можете во временную таблицу вставлять результаты и из неё уже финальную выборку делать.
Спасибо. Вот такую структуру собрал, но не работает, вообще у такой структуры есть шансы на жизнь? Может укажете на ошибки которые в глаза бросаются
CREATE TEMPORARY TABLE temp_table (value double, rdate timestamp, name text);
do $$
declare iCounter intenger:= 1;
declare iIter intenger:= 0;
declare iValue double:= NULL;
declare rDate timestamp:= NULL;
declare strName text:= NULL;
begin
while iCounter <= SELECT EXTRACT(DAY FROM TIMESTAMP '2024-07-19 00:00:00.00') loop
iIter = iIter + 1;
SELECT @iValue = case when h.recordtype = 'inner' then h.valdouble else NULL END AS dValue, @rDate = h.time, @strName = n.tagname FROM nodes_history h JOIN nodes n ON n.NodeId = h.NodeId
WHERE n.TagName = 'ASRMB.U_AVT12.FT0038.Out.Mt' AND (h.time BETWEEN (SELECT '2024-07-19'::timestamp - INTERVAL iIter + 1 DAY) AND (SELECT '2024-07-19'::timestamp - INTERVAL iIter DAY) AND h.recordtype != 'ubound' ORDER BY h.time DESC LIMIT 1
INSERT INTO temp_table VALUES (@iValue, @rDate, @strName);
end loop;
end $$;
Drop table temp_table;
|
|
|
|
|
Re: Выполнение запроса в цикле на уровне SQL запроса [сообщение #5279 является ответом на сообщение #5278] |
Mon, 22 July 2024 12:45 |
qwerty5000
Сообщений: 13 Зарегистрирован: July 2024
|
Junior Member |
|
|
Теперь что-то новое получаю (как мог упростил запрос):
Drop table temp_table;
CREATE TABLE temp_table (value integer, rdate timestamp, name text);
do $$
declare iCounter integer:= 1;
declare iIter integer:= 0;
declare iValue double precision:= NULL;
declare rDate timestamp:= NULL;
declare strName text:= NULL;
begin
while iIter < (SELECT EXTRACT(DAY FROM TIMESTAMP '2024-07-19 00:00:00.00')) loop
iIter = iIter + 1;
SELECT iValue = case when h.recordtype = 'inner' then h.valdouble else NULL END AS dValue, rDate = h.time, strName = n.tagname FROM nodes_history h JOIN nodes n ON n.NodeId = h.NodeId
WHERE n.TagName = 'ASRMB.U_AVT12.FT0038.Out.Mt' AND (h.time BETWEEN ('2024-07-15') AND ('2024-07-19')) AND h.recordtype != 'ubound' ORDER BY h.time DESC LIMIT 1;
INSERT INTO temp_table VALUES (iValue, rDate, strName);
end loop;
end $$;
select * from temp_table;
ПРЕДУПРЕЖДЕНИЕ: Обнаружен устаревший параметр конфигураци: 'aehistorianname'. Его поддержка будет прекращена в следующей версии!
ПРЕДУПРЕЖДЕНИЕ: Обнаружен устаревший параметр конфигураци: 'historianname'. Его поддержка будет прекращена в следующей версии!
ПРЕДУПРЕЖДЕНИЕ: Обнаружен устаревший параметр конфигураци: 'sourceae'. Его поддержка будет прекращена в следующей версии!
ПРЕДУПРЕЖДЕНИЕ: Обнаружен устаревший параметр конфигураци: 'sourceda'. Его поддержка будет прекращена в следующей версии!
ERROR: в запросе нет назначения для данных результата
HINT: Если вам нужно отбросить результаты SELECT, используйте PERFORM.
CONTEXT: функция PL/pgSQL inline_code_block, строка 10, оператор SQL-оператор
ОШИБКА: в запросе нет назначения для данных результата
SQL state: 42601
|
|
|
|
Re: Выполнение запроса в цикле на уровне SQL запроса [сообщение #5281 является ответом на сообщение #5280] |
Mon, 22 July 2024 15:32 |
qwerty5000
Сообщений: 13 Зарегистрирован: July 2024
|
Junior Member |
|
|
BlackEric писал(а) Mon, 22 July 2024 13:39declare strName text:= NULL;
begin
Вот этот begin, если я верно понял, не закрывается.
разобрался, вот такая конструкция работает, но почему-то когда начинаю вводить переменную вместо жесткой даты материт
Drop table temp_table;
CREATE TABLE temp_table (value integer, rdate timestamp, name text);
do $$
--declare iCounter integer:= 1;
declare iIter integer:= 0;
declare iValue double precision:= NULL;
declare reportDate timestamp:= '2024-07-19';
declare rDate timestamp:= NULL;
declare strName text:= NULL;
declare iDay int:= (SELECT EXTRACT(DAY FROM TIMESTAMP reportDate));
begin
while iIter < iDay loop
iIter = iIter + 1;
SELECT CASE WHEN h.recordtype = 'inner' THEN h.valdouble ELSE NULL END, h.time, n.tagname
INTO iValue, rDate, strName
FROM nodes_history h
JOIN nodes n ON n.NodeId = h.NodeId
WHERE n.TagName = 'ASRMB.U_AVT12.FT0038.Out.Mt' AND (h.time BETWEEN ('2024-07-18') AND ('2024-07-19')) AND h.recordtype != 'ubound' ORDER BY h.time DESC LIMIT 1;
INSERT INTO temp_table VALUES (iIter, rDate, strName);
end loop;
end $$;
select * from temp_table ;
ERROR: ошибка синтаксиса (примерное положение: "reportDate")
LINE 12: ...are iDay int:= (SELECT EXTRACT(DAY FROM TIMESTAMP reportDate...
^
ОШИБКА: ошибка синтаксиса (примерное положение: "reportDate")
SQL state: 42601
Character: 361
|
|
|
|
|
Переход к форуму:
Текущее время: Thu Nov 21 13:32:40 GMT+3 2024
Общее время, затраченное на создание страницы: 0.00850 секунд
|