Множественное представление JOIN на одной и той же таблице - PullRequest
2 голосов
/ 17 декабря 2010

У меня есть эта база данных для хранения данных датчиков,
Приобретения (acq) поступают из разных управляющих модулей (cu) через фиксированные интервалы (дата-время)
Каждое Приобретение имеет много разных показателей, хранящихся в таблице данных

acq
    id  
    datetime 
    id_cu     

data          
    id        
    id_acq  
    id_meas
    value

Мне нужен такой вид:

+---------------------+------+----+-----+
|      datetime       |  v1  | v2 |  v3 |
+---------------------+------+----+-----+
| 2010-09-13 00:05:00 | 40.9 |  1 | 0.3 |
| 2010-09-13 00:10:00 | 41.0 |  2 | 0.3 |
| 2010-09-13 00:15:00 | 41.1 |  4 | 0.3 |
+---------------------+------+----+-----+

AS:

  • v1 - это data.value (например, влажность)
    ГДЕ acq.id_cu = 1 И data.id_meas = 100

  • v2 - это значение data.value (например, счетчик)
    ГДЕ acq.id_cu = 2 И data.id_meas = 200

  • v3 - это data.value (например, температура)
    ГДЕ acq.id_cu = 3 И data.id_meas = 300

и т. Д. До десятка комбинаций, выбранных пользователем

Я закончил с этим запросом, но он всегда требует очень небольшого количества данных по сравнению с тем, который будет в производстве

SELECT a1.datetime, d1.value, d2.value, d3.value
FROM
    acq a1, data d1
    JOIN acq a2, data d2
        ON a2.id=d2.id_acq AND a2.datetime=a1.datetime
    JOIN acq a3, data d3
        ON a3.id=d3.id_acq AND a3.datetime=a1.datetime
WHERE a1.id=d1.id_acq
    AND a1.id_cu=1 AND d1.id_meas=100
    AND a2.id_cu=2 AND d2.id_meas=200
    AND a3.id_cu=3 AND d3.id_meas=300

Полагаю, было бы намного быстрее получать данные отдельно для каждого условия a1.id_centr=x AND d1.id_meas=y, а затем печатать данные, которые мне нужны, с моим приложением.

Каков наилучший (и правильный) способ добиться этого?

edit: при условии отсутствия недостатков в приобретениях, я имею в виду запуск этого:

SELECT datetime, value
FROM acq, data
WHERE acq.id=data.id_acq
    AND (
        id_cu=1 AND id_meas=100
        OR id_cu=2 AND id_meas=200
        OR id_cu=3 AND id_meas=300
    )
ORDER BY id_cu, id_meas

результаты разделения по id_cu / id_meas меняются и отображаются рядом друг с другом с использованием языка программирования (например, python + numpy), это вопрос сотен секунд против ... минут?

Ответы [ 2 ]

2 голосов
/ 17 декабря 2010

* Если предположить, что DATETIME и data.id_acq и cu и id_meas имеют индексы *, вы можете попробовать запрос UNION с фиктивными заполнителями столбцов и kludgey MAX ().Это должно работать, если ваши data.values ​​не являются отрицательными числами (и если они есть, вы можете просто выбрать чрезвычайно большое отрицательное число вместо нуля в качестве значения фиктивного заполнителя, число, выходящее далеко за пределы возможного диапазона):

    select FOO.datetime, max(FOO.v1), max(FOO.v2), max(FOO.v3)
    from
     (

     select acq.datetime, data.value as v1,0 as v2, 0 as v3
     from acq inner join data on acq.id = data.id_acq
     where acq.id_cu=1 and data.id_meas=100

     UNION

    select acq.datetime, 0 as v1, data.value as v2, 0 as v3
    from acq inner join data on acq.id = data.id_acq
    where acq.id_cu=2 and data.id_meas=200

    UNION

    select acq.datetime, 0 as v1, 0 v2, data.value as v3
    from acq inner join data on acq.id = data.id_acq
    where acq.id_cu=3 and data.id_meas=300
    ) as FOO
    group by FOO.datetime
1 голос
/ 17 декабря 2010

ваш JOINS немного сбивает с толку (поскольку вы смешиваете явное с неявным); попробуйте это:

SELECT a1.datetime, d1.value, d2.value, d3.value
FROM
    acq a1 
       INNER JOIN data d1 ON a1.id=d1.id_acq
       INNER JOIN acq a2  ON a2.datetime=a1.datetime
       INNER JOIN data d2 ON a2.id=d2.id_acq
       INNER JOIN acq a3  ON a3.datetime=a1.datetime
       INNER JOIN data d3 ON a3.id=d3.id_acq
WHERE 1=1
    AND a1.id_centr=1 AND d1.id_meas=100
    AND a2.id_centr=2 AND d2.id_meas=200
    AND a3.id_centr=3 AND d3.id_meas=300
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...