Simple-Scada forum

Simple-Scada 2 => Ваши вопросы => Тема начата: alan54 от 20 Сентября 2020, 17:23:10

Название: Как вытащить несколько данных из таблицы, соединяя ее саму с собой
Отправлено: alan54 от 20 Сентября 2020, 17:23:10
Здравствуйте. Требуется SQL-запросом вытащить из таблицы trends_data три связанных параметра с разными ID - количество (архивируется по изменению примерно 1 раз в минуту), ширину и длину (изменяются 1- 2 раза в сутки, архивируются 1 раз в час) и передать их в другую программу (1С).
Связать их можно только по timestamp, но как?
Пробовал "JOIN ... ON (DATE_FORMAT(a.timestamp, '%Y-%m-%d-%H') = DATE_FORMAT(b.timestamp, '%Y-%m-%d-%H'))" - при смене ширины и длины в период менее часа получаются неправильно связанные данные.
Пробовал ширину и длину архивировать по времени с интервалом 1 мин. - все равно архивируются 1 раз в час, потому что изменяются редко. Если бы их как-то удалось архивировать почаще, одновременно с изменением количества, то связать количество с шириной-длиной можно было бы поминутно (по DATE_FORMAT(timestamp, '%Y-%m-%d-%H-%i').
Но у меня не получилось.
Подскажите пожалуйста, как можно решить проблему.
Название: Re: Как вытащить несколько данных из таблицы, соединяя ее саму с собой
Отправлено: Simple-Scada от 21 Сентября 2020, 17:21:30
Здравствуйте.

При объединении разных выборок из "trends_data" возникает стандартная проблема связанная с тем, что строки в выборках в 99% случаев отличаются по времени и объединить их в одну таблицу сложно. Именно для решения этой проблемы в системе отчетов существует источник данных с типом "по-изменению". Принцип его работы (и то как он решает проблему объединения) подробно описан здесь (https://simple-scada.com/help/report/changesourcework.html). Используется два разных способа:
1. Заполнение недостающих данных предыдущими значениями;
2. Допустить погрешность по времени и объединить в одну строку несколько строк в пределах заданного пользователем времени (погрешности).
Оба способа реализуются автоматически сервером скады. Можно попробовать сделать что-то подобное и в MySQL, но скорее всего это будет сложно.
Название: Re: Как вытащить несколько данных из таблицы, соединяя ее саму с собой
Отправлено: alan54 от 21 Сентября 2020, 18:42:18
Спасибо, но это я знаю, и мне нужен не отчет, а результат запроса, который будет отображен в таблице 1С. Мне не понятно, почему нельзя сделать архививацию значений параметра через заданный интервал времени, даже если оно не изменяется?
Название: Re: Как вытащить несколько данных из таблицы, соединяя ее саму с собой
Отправлено: Simple-Scada от 21 Сентября 2020, 19:50:53
Мы не предлагаем сделать отчет, а ссылаемся на два варианта решения описанной Вами проблемы. Их можно использовать в MySQL при выборке, хотя средствами SQL это сложно сделать.

Цитировать
почему нельзя сделать архививацию значений параметра через заданный интервал времени, даже если оно не изменяется?
Потому что у это не даст практически никаких плюсов. Затраты на архивацию вырастут во много раз, вырастет количество запросов к СУБД, БД будет быстро расти в объёме, производительность выборок будет стремительно снижаться по мере роста таблицы и индексов, возникнут вопросы связанные с плохой производительностью системы архивации, медленной отрисовкой графиков и долгого построения отчетов. Чтобы метки времени совпадали до миллисекунд придётся пожертвовать точностью и сохранять в БД не реальные метки времени переменных, а округлённые. СУБД даже при небольшом количестве архивируемых переменных не будет успевать удалять старые данные из БД, по ограничению архива трендов (https://simple-scada.com/help/manual/editor-settings.html?anchor=set_trends), т.к. удаление наиболее тяжелая операция из-за перестраивания индексов, а в условиях постоянной архивации по времени удалять придётся много. И всё ради того чтобы объединить строки в разных выборках, это слишком редкая задача. Если в будущем она будет более востребована, то мы скорее всего добавим возможность выполнить выборку средствами скады (а не пользовательского SQL-запроса). Т.е. возможность получить такую выборку, которую сервер скады формирует при построении источника данных с типом по-изменению.
Название: Re: Как вытащить несколько данных из таблицы, соединяя ее саму с собой
Отправлено: alan54 от 21 Сентября 2020, 21:14:13
Чтобы метки времени совпадали до миллисекунд придётся пожертвовать точностью и сохранять в БД не реальные метки времени переменных, а округлённые.
Это совсем не обязательно. Архивация переменных длины и ширины (которые изменяются редко) у меня прописана в событии OnDataChange переменной количества (которая меняется примерно 1 раз в минуту и архивируется по изменению). Но, несмотря на то, что архивация длины и ширины задана по времени (1 мин.), из-за того, что эти величины остаются относительно постоянными (изменяются 1-2 раза в сутки), сервер их не архивирует, точнее, архивирует 1 раз в час. Для чего тогда нужен тип архивации "По времени", если все равно работает тип "По изменению", непонятно.
Название: Re: Как вытащить несколько данных из таблицы, соединяя ее саму с собой
Отправлено: Simple-Scada от 21 Сентября 2020, 21:21:20
Подробное описание типов архивации и их разницы доступно по ссылке (https://simple-scada.com/help/manual/variable-new.html?anchor=var_archive). Архивация по времени нужна, когда требуется ещё сильнее проредить тренд, чем при архивации по-изменению. Тренд построенный с архивацией по времени и тренд по-изменению могут сильно различаться. Это не архивация через каждые N секунд.
Название: Re: Как вытащить несколько данных из таблицы, соединяя ее саму с собой
Отправлено: alan54 от 21 Сентября 2020, 21:32:07
Почему тогда у меня не срабатывает тип архивации "Комбинированный", который, согласно руководству, "Спустя "Интервал архивации" значение принудительно запишется в архив (даже несмотря на то, что оно не превысило зону нечувствительности)". Может, надо поиграться с зоной нечувствительности? Ширина и длина - целые 3-4-х значные числа.
Название: Re: Как вытащить несколько данных из таблицы, соединяя ее саму с собой
Отправлено: Simple-Scada от 22 Сентября 2020, 11:43:22
Потому что переменная не изменилась. Если переменная не меняла своё значение, то просто ничего не произойдёт и новая точка тренда не будет создана, независимо от типа архивации. Точки трендов создаются только при изменении переменной (либо при длительном простое более часа).
В Simple-Scada среди трёх типов архивации нет ни одного который выполняет архивацию по времени через каждые N секунд по причинам описанным в этом сообщении (https://simple-scada.com/forum/index.php?topic=1093.msg8882#msg8882). Если бы такой способ был, мы бы написали об этом в первом ответе этой темы. Если только один способ добавления точек в БД с равными метками времени: создать отдельную таблицу в БД с нужной структурой и добавлять в неё записи с одинаковыми метками через пользовательские SQL запросы (RunSQL).
Название: Re: Как вытащить несколько данных из таблицы, соединяя ее саму с собой
Отправлено: alan54 от 22 Сентября 2020, 12:54:48
Спасибо за последний совет (насчет отдельной таблицы), надо попробовать.