Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Не получили письмо с кодом активации?

Официальный форум Simple-Scada.

Автор Тема: Как вытащить несколько данных из таблицы, соединяя ее саму с собой  (Прочитано 1832 раз)

alan54

  • Постоялец
  • ***
  • Сообщений: 145
    • Просмотр профиля
Здравствуйте. Требуется 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').
Но у меня не получилось.
Подскажите пожалуйста, как можно решить проблему.
« Изменён: 20 Сентября 2020, 22:00:57 от alan54 »

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 2998
    • Просмотр профиля
    • Simple-Scada
Здравствуйте.

При объединении разных выборок из "trends_data" возникает стандартная проблема связанная с тем, что строки в выборках в 99% случаев отличаются по времени и объединить их в одну таблицу сложно. Именно для решения этой проблемы в системе отчетов существует источник данных с типом "по-изменению". Принцип его работы (и то как он решает проблему объединения) подробно описан здесь. Используется два разных способа:
1. Заполнение недостающих данных предыдущими значениями;
2. Допустить погрешность по времени и объединить в одну строку несколько строк в пределах заданного пользователем времени (погрешности).
Оба способа реализуются автоматически сервером скады. Можно попробовать сделать что-то подобное и в MySQL, но скорее всего это будет сложно.

alan54

  • Постоялец
  • ***
  • Сообщений: 145
    • Просмотр профиля
Спасибо, но это я знаю, и мне нужен не отчет, а результат запроса, который будет отображен в таблице 1С. Мне не понятно, почему нельзя сделать архививацию значений параметра через заданный интервал времени, даже если оно не изменяется?

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 2998
    • Просмотр профиля
    • Simple-Scada
Мы не предлагаем сделать отчет, а ссылаемся на два варианта решения описанной Вами проблемы. Их можно использовать в MySQL при выборке, хотя средствами SQL это сложно сделать.

Цитировать
почему нельзя сделать архививацию значений параметра через заданный интервал времени, даже если оно не изменяется?
Потому что у это не даст практически никаких плюсов. Затраты на архивацию вырастут во много раз, вырастет количество запросов к СУБД, БД будет быстро расти в объёме, производительность выборок будет стремительно снижаться по мере роста таблицы и индексов, возникнут вопросы связанные с плохой производительностью системы архивации, медленной отрисовкой графиков и долгого построения отчетов. Чтобы метки времени совпадали до миллисекунд придётся пожертвовать точностью и сохранять в БД не реальные метки времени переменных, а округлённые. СУБД даже при небольшом количестве архивируемых переменных не будет успевать удалять старые данные из БД, по ограничению архива трендов, т.к. удаление наиболее тяжелая операция из-за перестраивания индексов, а в условиях постоянной архивации по времени удалять придётся много. И всё ради того чтобы объединить строки в разных выборках, это слишком редкая задача. Если в будущем она будет более востребована, то мы скорее всего добавим возможность выполнить выборку средствами скады (а не пользовательского SQL-запроса). Т.е. возможность получить такую выборку, которую сервер скады формирует при построении источника данных с типом по-изменению.
« Изменён: 21 Сентября 2020, 19:52:59 от Simple-Scada »

alan54

  • Постоялец
  • ***
  • Сообщений: 145
    • Просмотр профиля
Чтобы метки времени совпадали до миллисекунд придётся пожертвовать точностью и сохранять в БД не реальные метки времени переменных, а округлённые.
Это совсем не обязательно. Архивация переменных длины и ширины (которые изменяются редко) у меня прописана в событии OnDataChange переменной количества (которая меняется примерно 1 раз в минуту и архивируется по изменению). Но, несмотря на то, что архивация длины и ширины задана по времени (1 мин.), из-за того, что эти величины остаются относительно постоянными (изменяются 1-2 раза в сутки), сервер их не архивирует, точнее, архивирует 1 раз в час. Для чего тогда нужен тип архивации "По времени", если все равно работает тип "По изменению", непонятно.
« Изменён: 21 Сентября 2020, 21:17:24 от alan54 »

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 2998
    • Просмотр профиля
    • Simple-Scada
Подробное описание типов архивации и их разницы доступно по ссылке. Архивация по времени нужна, когда требуется ещё сильнее проредить тренд, чем при архивации по-изменению. Тренд построенный с архивацией по времени и тренд по-изменению могут сильно различаться. Это не архивация через каждые N секунд.
« Изменён: 21 Сентября 2020, 21:26:19 от Simple-Scada »

alan54

  • Постоялец
  • ***
  • Сообщений: 145
    • Просмотр профиля
Почему тогда у меня не срабатывает тип архивации "Комбинированный", который, согласно руководству, "Спустя "Интервал архивации" значение принудительно запишется в архив (даже несмотря на то, что оно не превысило зону нечувствительности)". Может, надо поиграться с зоной нечувствительности? Ширина и длина - целые 3-4-х значные числа.
« Изменён: 21 Сентября 2020, 21:33:35 от alan54 »

Simple-Scada

  • Администратор
  • *****
  • Сообщений: 2998
    • Просмотр профиля
    • Simple-Scada
Потому что переменная не изменилась. Если переменная не меняла своё значение, то просто ничего не произойдёт и новая точка тренда не будет создана, независимо от типа архивации. Точки трендов создаются только при изменении переменной (либо при длительном простое более часа).
В Simple-Scada среди трёх типов архивации нет ни одного который выполняет архивацию по времени через каждые N секунд по причинам описанным в этом сообщении. Если бы такой способ был, мы бы написали об этом в первом ответе этой темы. Если только один способ добавления точек в БД с равными метками времени: создать отдельную таблицу в БД с нужной структурой и добавлять в неё записи с одинаковыми метками через пользовательские SQL запросы (RunSQL).
« Изменён: 22 Сентября 2020, 11:45:30 от Simple-Scada »

alan54

  • Постоялец
  • ***
  • Сообщений: 145
    • Просмотр профиля
Спасибо за последний совет (насчет отдельной таблицы), надо попробовать.