Запросы историка данных - PullRequest
0 голосов
/ 13 ноября 2009

У меня есть таблица, которая содержит данные для электродвигателей в формате:

ДАТА (DateTime) | TagName (VarChar (50) | Val (Float) |


2009-11-03 17: 44: 13.000 | Motor_1 | 123,45


2009-11-04 17: 44: 13.000 | Motor_1 | 124,45


2009-11-05 17: 44: 13.000 | Motor_1 | 125,45


2009-11-03 17: 44: 13.000 | Motor_2 | 223,45


2009-11-04 17: 44: 13.000 | Motor_2 | 224,45

Данные для каждого двигателя вставляются ежедневно, поэтому будет 31 Motor_1s и 31 Motor_2s и т. Д. Мы делаем это, чтобы отслеживать это на экранах нашей системы управления. Я использую представления для извлечения максимальных значений за последние месяцы и минимальных значений за последние месяцы. То же самое для данных за эти месяцы. Затем я присоединяюсь к двум и вычисляю разницу чтобы получить фактические часы работы за этот месяц. «Вал» не подлежит изменению Накопление от ПЛК (Контроллер). Это мой запрос за последние месяцы Макс Значение:

SELECT     TagName, Val AS Hours
FROM         dbo.All_Data_From_Last_Mon AS cur
WHERE     (NOT EXISTS
                          (SELECT     TagName, Val
                            FROM          dbo.All_Data_From_Last_Mon AS high
                            WHERE      (TagName = cur.TagName) AND (Val > cur.Val)))

Это мой запрос за последние месяцы Макс Значение:

SELECT     TagName, Val AS Hours
FROM         dbo.All_Data_From_Last_Mon AS cur
WHERE     (NOT EXISTS
                          (SELECT     TagName, Val
                            FROM          dbo.All_Data_From_Last_Mon AS high
                            WHERE      (TagName = cur.TagName) AND (Val < cur.Val)))

Это запрос, который вычисляет разницу и работает немного медленно:

SELECT  dbo.Motors_Last_Mon_Max.TagName, STR(dbo.Motors_Last_Mon_Max.Hours - dbo.Motors_Last_Mon_Min.Hours, 12, 2) AS Hours
FROM    dbo.Motors_Last_Mon_Min RIGHT OUTER JOIN
            dbo.Motors_Last_Mon_Max ON dbo.Motors_Last_Mon_Min.TagName = dbo.Motors_Last_Mon_Max.TagName

Я знаю, что есть лучший способ. В конечном итоге мне просто нужно общее количество последних месяцев и общее количество месяцев. Любая помощь будет оценена.

Заранее спасибо

1 Ответ

0 голосов
/ 13 ноября 2009

Первые два запроса могут быть обработаны как один. Что-то вроде:

SELECT TagName, MAX(Val) AS MaxVal, MIN(Val) AS MinVal
FROM   dbo.All_Data_From_Last_Mon
GROUP BY TagName
-- ORDER BY TagName  (optionally)

Теперь я вижу, что эти запросы являются представлениями SQL, используемыми для третьего запроса ... и я понимаю, почему это будет медленно; -)
Следующее воспроизводит логику, но без представлений, и это должно позволить SQL немного оптимизироваться. Во всяком случае, это дает больше ясности относительно того, что делается ...
Пожалуйста, "дай ему спину".

SELECT  DISTINCT Mx.TagName, STR(Mx.Hours - Mn.Hours, 12, 2) AS Hours
FROM  dbo.All_Data_From_Last_Mon Mx
RIGHT OUTER JOIN dbo.All_Data_From_Last_Mon Mn ON Mx.TagName = Mn.TagName
  AND dbo.All_Data_From_Last_Mon  -- Cut the cross product a bit; may not be necessary
WHERE 
      NOT EXISTS (SELECT * FROM dbo.All_Data_From_Last_Mon Mx1 
                  WHERE Mx1.TagName = Mx.TagName AND Mx1.Hours > Mx.Hours)
  AND NOT EXISTS (SELECT * FROM dbo.All_Data_From_Last_Mon Mn1 
                  WHERE Mn1.TagName = Mn.TagName AND Mn1.Hours < Mx.Hours)

Примечания:
- обратите внимание на DISTINCT в операторе SELECT. Это делается для того, чтобы избежать дублирования строк в случае, если бы в течение нескольких дней было показано максимальное количество часов (или минимум) для этого месяца.
- дополнительное условие в соединении направлено на то, чтобы избежать полного перекрестного произведения 31 * 31, но условия, которые действительно приводят его к одной строке (или нескольким в случае спадов), являются предикатами NON EXISTS, которые следуют ниже. - Индекс TagName + Hours, если его нет, очень помог бы.

==> Мне будут интересны отзывы об эффективности этого запроса, так как они работают с фактическими данными.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...