| Начало » Использование СУБД » 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:26 qwerty5000 писал(а) Fri, 19 July 2024 15:09Спасибо. Вот такую структуру собрал, но не работает, вообще у такой структуры есть шансы на жизнь? Может укажете на ошибки которые в глаза бросаютсяBlackEric писал(а) Fri, 19 July 2024 13:37Можете во временную таблицу вставлять результаты и из неё уже финальную выборку делать.While 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:39 declare 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 |  
	|  |  |  
	|  |  
	|  | 
 
 
 Текущее время: Fri Oct 31 22:37:14 GMT+3 2025 
 Общее время, затраченное на создание страницы: 0.00894 секунд |