Чтение всех последних измеренных значений измерительного устройства - PullRequest
1 голос
/ 24 февраля 2020

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

id | date             | device_id | measurement_id | value
---+------------------+-----------+----------------+------
1  | 2020-02-24 20:00 | 3         | 1              | 7.9
2  | 2020-02-24 20:00 | 3         | 2              | 3.2
3  | 2020-02-24 20:00 | 3         | 3              | 5.12
4  | 2020-02-24 20:00 | 1         | 1              | 7.9
5  | 2020-02-24 20:00 | 1         | 2              | 3.2
6  | 2020-02-24 20:00 | 1         | 3              | 5.12
7  | 2020-02-24 20:10 | 1         | 1              | 15.2
8  | 2020-02-24 20:10 | 1         | 2              | 5.8
9  | 2020-02-24 20:10 | 1         | 3              | 9.1
10 | 2020-02-24 20:10 | 2         | 1              | 4.6
11 | 2020-02-24 20:10 | 2         | 2              | 2.3
12 | 2020-02-24 20:20 | 1         | 4              | 45.1

Теперь я хочу прочитать последнее значение каждого measure_id в зависимости от device_id . Итак, в этом примере (для device_id 1):

id | date             | device_id | measurement_id | value
---+------------------+-----------+----------------+------
7  | 2020-02-24 20:10 | 1         | 1              | 15.2
8  | 2020-02-24 20:10 | 1         | 2              | 5.8
9  | 2020-02-24 20:10 | 1         | 3              | 9.1
12 | 2020-02-24 20:20 | 1         | 4              | 45.1

Как мне лучше всего это реализовать с T- SQL на Azure SQL Сервере?

Ответы [ 5 ]

1 голос
/ 25 февраля 2020

Пожалуйста, запустите этот код ниже, я проверил, и он работает хорошо, отфильтруйте device_id=1:

select * from dbo.test11 where value IN (
    select Max(value) FROM 
            (select * from test11 where device_id=1) tb2  group by tb2.measurement_id
        )

Создайте таблицу, содержащую те же данные с вами:

enter image description here

Выполните запрос и получите результат:

enter image description here

Надеюсь, это поможет.

1 голос
/ 24 февраля 2020

При правильных индексах коррелированный подзапрос часто имеет наилучшую производительность:

select t.*
from t
where t.device = 1 and
      t.date = (select max(t2.date) 
                from t t2 
                where t2.device_id = t.device_id and
                      t2.measurement_id = t.measurement_id
               );

Требуемый индекс находится на (device_id, measurement_id, date).

Каноническое решение использует row_number() и работает почти так же хорошо.

1 голос
/ 24 февраля 2020

Попробуй, не проверял ...

select * 
from my_table mt1 
where mt1.date = (select max(mt2.date) 
                   from my_table mt2 
                   where mt2.device_id = mt1.device_id 
                   and  mt2.measurement_id = mt1.measurement_id
                   )
1 голос
/ 24 февраля 2020

Вы можете использовать функцию row_number для получения последней записи для каждого идентификатора устройства и идентификатора измерения:

select a.*
from
(select *,
       row_number() over(partition by device_id,measurement_id order by date desc) as rownum
from table) a
where a.rownum=1
0 голосов
/ 24 февраля 2020

Довольно простой. Вы захотите использовать как оператор MAX, так и предложение GroupBy. Попробуйте, и если вам нужно больше конкретных c примеров, я могу вам помочь.

-Matt-

...