2015-07-22 3 views
0

Итак, у меня есть эта злая длинная и сложная хранимая процедура, которую я построил на основе учебников для «поворота». Мне было интересно, сможет ли кто-нибудь, кто владеет MySQL, обсуждать со мной, как сделать это чище и/или работать лучше. Кроме того, когда запрос не возвращает результатов между указанными датами, он выдает синтаксическую ошибку MySQL в предложении «read_pivot (...)».Есть ли способ оптимизировать эту хранимую процедуру?

Вот код:

DELIMITER $$ 
CREATE DEFINER=`csonet_web_user`@`%` PROCEDURE `reading_pivot`(
    IN begin_date datetime, 
    IN end_date datetime, 
    IN node_string varchar(255), 
    IN sensor_string varchar(255) 
) 
BEGIN 
SET session group_concat_max_len = 4096; 
SET @sql = null; 
SELECT group_concat(distinct concat('MAX(IF(sensorId = ''', sensorId, ''', collectedValue * multiplier + offset, NULL)) AS ''', sensorId,'''')) INTO @sql FROM 
    (
     SELECT inodes.id AS nodeId, from_unixtime(300 * round(unix_timestamp(inodes_data.time)/300)) AS dateCollected, TRIM(inodes.descr) AS parentId, 
     1 AS sensorNumber, CONCAT('c', TRIM(cast(inodes.id as char(6) charset latin1)), '_1') AS sensorId, inodes.sensType1 AS sensorTitle, inodes.a1 AS multiplier, inodes.b1 AS offset, inodes_data.sens1 AS collectedValue, 
     inodes_structure_data.sensor1_units AS unitsOfMeasure 
      FROM CSO_CITY_15.inodes 
      INNER JOIN CSO_CITY_15.inodes_structure_data 
       ON inodes.id = inodes_structure_data.id 
      INNER JOIN CSO_CITY_15.inodes_data inodes_data 
       ON inodes.id = inodes_data.i_id 
      WHERE find_in_set(TRIM(cast(inodes.id as char(6) charset latin1)), node_string) 
       AND inodes_data.time BETWEEN begin_date AND end_date 

     UNION ALL 

     SELECT inodes.id, from_unixtime(300 * round(unix_timestamp(inodes_data.time)/300)), TRIM(inodes.descr), 
     2, CONCAT('c', TRIM(cast(inodes.id as char(6) charset latin1)), '_2'), inodes.sensType2, inodes.a2, inodes.b2, inodes_data.sens2, inodes_structure_data.sensor2_units 
      FROM CSO_CITY_15.inodes 
      INNER JOIN CSO_CITY_15.inodes_structure_data 
       ON inodes.id = inodes_structure_data.id 
      INNER JOIN CSO_CITY_15.inodes_data inodes_data 
       ON inodes.id = inodes_data.i_id 
      WHERE find_in_set(TRIM(cast(inodes.id as char(6) charset latin1)), node_string) 
       AND inodes_data.time BETWEEN begin_date AND end_date 

     UNION ALL 

     SELECT inodes.id, from_unixtime(300 * round(unix_timestamp(inodes_data.time)/300)), TRIM(inodes.descr), 
     3, CONCAT('c', TRIM(cast(inodes.id as char(6) charset latin1)), '_3'), inodes.sensType3, inodes.a3, inodes.b3, inodes_data.sens3, inodes_structure_data.sensor3_units 
      FROM CSO_CITY_15.inodes 
      INNER JOIN CSO_CITY_15.inodes_structure_data 
       ON inodes.id = inodes_structure_data.id 
      INNER JOIN CSO_CITY_15.inodes_data inodes_data 
       ON inodes.id = inodes_data.i_id 
      WHERE find_in_set(TRIM(cast(inodes.id as char(6) charset latin1)), node_string) 
       AND inodes_data.time BETWEEN begin_date AND end_date 

     UNION ALL 

     SELECT inodes.id, from_unixtime(300 * round(unix_timestamp(inodes_data.time)/300)), TRIM(inodes.descr), 
     4, CONCAT('c', TRIM(cast(inodes.id as char(6) charset latin1)), '_4'), inodes.sensType4, inodes.a4, inodes.b4, inodes_data.sens4, inodes_structure_data.sensor4_units 
      FROM CSO_CITY_15.inodes 
      INNER JOIN CSO_CITY_15.inodes_structure_data 
       ON inodes.id = inodes_structure_data.id 
      INNER JOIN CSO_CITY_15.inodes_data inodes_data 
       ON inodes.id = inodes_data.i_id 
      WHERE find_in_set(TRIM(cast(inodes.id as char(6) charset latin1)), node_string) 
       AND inodes_data.time BETWEEN begin_date AND end_date 

    ) sensor_reading 
WHERE 
    find_in_set(sensorId, sensor_string) 
ORDER BY dateCollected; 

SET @sql = concat('SELECT dateCollected, ', @sql, ' FROM (
     SELECT inodes.id AS nodeId, from_unixtime(300 * round(unix_timestamp(inodes_data.time)/300)) AS dateCollected, TRIM(inodes.descr) AS parentId, 
     1 AS sensorNumber, CONCAT(''c'', TRIM(cast(inodes.id as char(6) charset latin1)), ''_1'') AS sensorId, inodes.sensType1 AS sensorTitle, inodes.a1 AS multiplier, inodes.b1 AS offset, inodes_data.sens1 AS collectedValue, 
     inodes_structure_data.sensor1_units AS unitsOfMeasure 
      FROM CSO_CITY_15.inodes 
      INNER JOIN CSO_CITY_15.inodes_structure_data 
       ON inodes.id = inodes_structure_data.id 
      INNER JOIN CSO_CITY_15.inodes_data inodes_data 
       ON inodes.id = inodes_data.i_id 
      WHERE find_in_set(TRIM(cast(inodes.id as char(6) charset latin1)), ''',node_string,''') 
       AND inodes_data.time BETWEEN ''',begin_date,''' AND ''',end_date,''' 

     UNION ALL 

     SELECT inodes.id, from_unixtime(300 * round(unix_timestamp(inodes_data.time)/300)), TRIM(inodes.descr), 
     2, CONCAT(''c'', TRIM(cast(inodes.id as char(6) charset latin1)), ''_2''), inodes.sensType2, inodes.a2, inodes.b2, inodes_data.sens2, inodes_structure_data.sensor2_units 
      FROM CSO_CITY_15.inodes 
      INNER JOIN CSO_CITY_15.inodes_structure_data 
       ON inodes.id = inodes_structure_data.id 
      INNER JOIN CSO_CITY_15.inodes_data inodes_data 
       ON inodes.id = inodes_data.i_id 
      WHERE find_in_set(TRIM(cast(inodes.id as char(6) charset latin1)), ''',node_string,''') 
       AND inodes_data.time BETWEEN ''',begin_date,''' AND ''',end_date,''' 

     UNION ALL 

     SELECT inodes.id, from_unixtime(300 * round(unix_timestamp(inodes_data.time)/300)), TRIM(inodes.descr), 
     3, CONCAT(''c'', TRIM(cast(inodes.id as char(6) charset latin1)), ''_3''), inodes.sensType3, inodes.a3, inodes.b3, inodes_data.sens3, inodes_structure_data.sensor3_units 
      FROM CSO_CITY_15.inodes 
      INNER JOIN CSO_CITY_15.inodes_structure_data 
       ON inodes.id = inodes_structure_data.id 
      INNER JOIN CSO_CITY_15.inodes_data inodes_data 
       ON inodes.id = inodes_data.i_id 
      WHERE find_in_set(TRIM(cast(inodes.id as char(6) charset latin1)), ''',node_string,''') 
       AND inodes_data.time BETWEEN ''',begin_date,''' AND ''',end_date,''' 

     UNION ALL 

     SELECT inodes.id, from_unixtime(300 * round(unix_timestamp(inodes_data.time)/300)), TRIM(inodes.descr), 
     4, CONCAT(''c'', TRIM(cast(inodes.id as char(6) charset latin1)), ''_4''), inodes.sensType4, inodes.a4, inodes.b4, inodes_data.sens4, inodes_structure_data.sensor4_units 
      FROM CSO_CITY_15.inodes 
      INNER JOIN CSO_CITY_15.inodes_structure_data 
       ON inodes.id = inodes_structure_data.id 
      INNER JOIN CSO_CITY_15.inodes_data inodes_data 
       ON inodes.id = inodes_data.i_id 
      WHERE find_in_set(TRIM(cast(inodes.id as char(6) charset latin1)), ''',node_string,''') 
       AND inodes_data.time BETWEEN ''',begin_date,''' AND ''',end_date,''' 

    ) sensor_reading WHERE 
    find_in_set(sensorId, ''',sensor_string,''') 
group by dateCollected'); 

PREPARE stmt FROM @sql; 
EXECUTE stmt; 

END$$ 
DELIMITER ; 

Результаты Примеры для call CSO_CITY_3.reading_pivot('2015-07-07','2015-07-08','26121','c26121_1,c26121_2')

+---------------------+--------------------+--------------------+ 
| dateCollected  | c26121_1   | c26121_2   | 
+---------------------+--------------------+--------------------+ 
| 2015-07-07 00:00:00 | 0.8928999044001102 | 1.73075295612216 | 
| 2015-07-07 00:05:00 | 0.8787019047886133 | 1.73075295612216 | 
| 2015-07-07 00:10:00 | 0.8928999044001102 | 1.759125955402851 | 
| 2015-07-07 00:15:00 | 0.8787019047886133 | 1.73075295612216 | 
| 2015-07-07 00:20:00 | 0.8928999044001102 | 1.7023799568414688 | 
| 2015-07-07 00:25:00 | 0.8928999044001102 | 1.759125955402851 | 
| 2015-07-07 00:30:00 | 0.8928999044001102 | 1.73075295612216 | 
| 2015-07-07 00:35:00 | 0.9070979040116072 | 1.759125955402851 | 
| 2015-07-07 00:40:00 | 0.8787019047886133 | 1.73075295612216 | 
| 2015-07-07 00:45:00 | 0.8928999044001102 | 1.73075295612216 | 
| 2015-07-07 00:50:00 | 0.935493903234601 | 1.7023799568414688 | 
| 2015-07-07 00:55:00 | 0.8928999044001102 | 1.73075295612216 | 
| 2015-07-07 01:00:00 | 0.8928999044001102 | 1.73075295612216 | 
| 2015-07-07 01:05:00 | 0.8928999044001102 | 1.73075295612216 | 

Любые и вся помощь или руководство высоко ценится!

ответ

0

Я предлагаю вам динамически построить запрос, а затем выполнить его. Here - пример и как он работает.

Смежные вопросы