SQL: вычислить столбец с динамическими сводными запросами - PullRequest
1 голос
/ 26 марта 2019

В моей базе данных есть таблица со всеми измерениями датчиков. Названия этих датчиков указаны в другой таблице в базе данных. Я хотел бы создать поворотный вид с отметкой даты и времени измерений и именами датчиков в виде столбцов. Я хотел бы использовать некоторые из этих столбцов для вычисления новой «переменной».

Оригинальная таблица:

Id  | DateTime              | SensorId  | Value
100 | 2019-01-01 00:00:00   | 1         | 19
101 | 2019-01-01 00:05:00   | 1         | 19
102 | 2019-01-01 00:10:00   | 1         | 19
109 | 2019-01-01 00:00:00   | 2         | 44,4
110 | 2019-01-01 00:05:00   | 2         | 44,3
111 | 2019-01-01 00:10:00   | 2         | 44,1
118 | 2019-01-01 00:00:00   | 3         | 338
119 | 2019-01-01 00:05:00   | 3         | 335
120 | 2019-01-01 00:10:00   | 3         | 330

У меня есть две части кода, но я не знаю, как «объединить» нужные мне части.

Сначала я создал простую сводную таблицу с:

DECLARE @cols  AS NVARCHAR(MAX)='';
DECLARE @query AS NVARCHAR(MAX)='';
DECLARE @query2 AS NVARCHAR(MAX)='';

SELECT @cols = @cols + QUOTENAME([SensorId]) + ',' FROM (select distinct [SensorId] from [dbo].[Measurement] ) as tmp
select @cols = substring(@cols, 0, len(@cols)) --trim "," at end

set @query = 
'SELECT [DateTime], [1] , [2], [3], [1] * [2] from 
(
    select [DateTime], [Value], [SensorId] from [dbo].[Measurement]
) src
pivot 
(
    max([Value]) for [SensorId] in (' + @cols + ')
) piv'

execute(@query)

Это создает:

DateTime            | 1     | 2     | 3     | Calculated column
2019-01-01 00:00:00 | 19    | 44,4  | 338   | 843,6
2019-01-01 00:05:00 | 19    | 44,3  | 335   | 841,7
2019-01-01 00:10:00 | 19    | 44,1  | 330   | 837,9

Но в этой таблице столбцы пронумерованы (вместо именованных), и мне нужно знать, сколько у меня датчиков.

Мне также удалось получить сводную динамическую таблицу с именами датчиков с помощью этого запроса:

DECLARE @columns NVARCHAR(MAX), @sql NVARCHAR(MAX);
SET @columns = N'';
SELECT @columns += N', p.' + QUOTENAME(Unicode)
  FROM (SELECT  distinct dbo.Unicode.Code as Unicode
FROM     dbo.Measurement INNER JOIN
                  dbo.Sensor ON Sensor.Id = Measurement.SensorId INNER JOIN
                  dbo.SensorModel on SensorModel.Id = Sensor.Id INNER JOIN
                  dbo.Unicode on Unicode.Id = SensorModel.UnicodeId) AS x;
SET @sql = N'
SELECT ' + STUFF(@columns, 1, 2, '') + ' 
FROM
(
  Select dbo.Measurement.DateTime, dbo.Unicode.Code as Unicode, dbo.Measurement.Value as value
FROM     dbo.Measurement INNER JOIN
                  dbo.Sensor ON Sensor.Id = Measurement.SensorId INNER JOIN
                  dbo.SensorModel on SensorModel.Id = Sensor.Id INNER JOIN
                  dbo.Unicode on Unicode.Id = SensorModel.UnicodeId
) AS j
PIVOT
(
  max(value) FOR Unicode IN ('
  + STUFF(REPLACE(@columns, ', p.[', ',['), 1, 1, '')
  + ')
) AS p;';

PRINT @sql;
EXEC sp_executesql @sql;

Результат:

Temperature1    | Temperature2
44,4            | 338
44,3            | 335
44,1            | 330

Однако я не знаю, как добавить Datetime и вычислить дополнительную переменную. Я знаю, какие сенсорные имена я хотел бы умножить. Так что я подумал, что это будет что-то вроде ... SELECT [DateTime], ' + STUFF(@columns, 1, 2, '') + ' [Temperature1]*[Temperature2] FROM ..., но это, конечно, не поможет.

Чтобы быть ясным, я хотел бы иметь этот стол:

    DateTime            | Temperature1 | Temperature2 | Calculated column
    2019-01-01 00:00:00 | 19           | 44,4         | 843,6
    2019-01-01 00:05:00 | 19           | 44,3         | 841,7
    2019-01-01 00:10:00 | 19           | 44,1         | 837,9
...