0

私は次のSQLを持っています:

SELECT devices.device_id,
   devices.description,
   sensors.sensor_id,
   sensors.description,
   measurements.value,
   measurements.valueDate,
   measurements.created_at
FROM measurements
INNER JOIN sensors
   ON sensors.id = measurements.sensor_id
INNER JOIN devices
   ON devices.id = sensors.device_id
WHERE devices.device_id = '123456'
   AND sensors.sensor_id = '100102'
   AND measurements.created_at < (
      SELECT created_at
      FROM measurements
      ORDER BY created_at DESC LIMIT 1
      )
   AND measurements.created_at > DATE_ADD((
         SELECT created_at
         FROM measurements
         ORDER BY created_at DESC LIMIT 1
         ), INTERVAL - 48 DAY)

問題は最後の 2 行にあると思います...測定テーブル全体ではなく、内部結合テーブルを参照する日付から過去 48 日間を取得したいと思います。結合テーブルの結果に属する列を参照する方法がわかりません。結合テーブルにエイリアスを設定する必要がありますか?

テーブルは次のとおりです。

Devices
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `user_id` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `device_id` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `description` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
  `country_name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `city` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',

Sensors
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `device_id` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `sensor_id` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `description` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
  `state` tinyint(1) NOT NULL,
  `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',

Mesurements
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `sensor_id` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `valueDate` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
  `value` float(8,2) NOT NULL,
  `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
4

1 に答える 1

1

考えられる解決策:

SELECT devices.device_id,
       devices.description,
       sensors.sensor_id,
       sensors.description,
       m.value,
       m.valueDate,
       m.created_at
FROM (
   SELECT max( m.created_at ) max_date,
          max( m.created_at ) - interval 48 day min_date
   FROM measurements m
   INNER JOIN sensors
      ON sensors.id = m.sensor_id
   INNER JOIN devices
      ON devices.id = sensors.device_id
   WHERE devices.device_id = '123456'
      AND sensors.sensor_id = '100102'
) q
JOIN measurements m
ON m.created_at BETWEEN q.min_date AND q.max_date
INNER JOIN sensors
      ON sensors.id = m.sensor_id
INNER JOIN devices
      ON devices.id = sensors.device_id
WHERE devices.device_id = '123456'
      AND sensors.sensor_id = '100102'

デモ: http://www.sqlfiddle.com/#!2/73a5d/3


備考:

クエリは、次の比較を使用してテーブルを結合しています。

  • センサー.id = 測定値.センサー_id
  • ON devices.id = センサー.device_id

それは言及する価値があります:

  • sensors.idはタイプですがint(10)measurements.sensor_idはタイプですvarchar(255)
  • devices.idはタイプですがint(10)sensors.device_idはタイプですvarchar(255)

テーブル構造の設計に欠陥があり、再設計する必要があるのはおそらく歌です。これは、MySql が文字列から数値 (またはその逆) へのキャストを継続的に実行する必要があるため、パフォーマンスに影響します。

于 2013-10-26T13:59:09.830 に答える