SQL SELECT多个表上的一个值

时间:2014-03-16 11:33:31

标签: mysql sql join multiple-tables

我正在使用6个表进行传感器测量。

DEVICES
id imei        name
1  123456789   device1

BMP085
id deviceId date        time     pressure altitude tempC tempF
1  1        2014-02-21  20:01:02 000.00   000.00   00.00 00.00

GPS
id deviceId date       time     latitude longitude timeUtc  timeFix  altitude eps   epx   epv   ept   speed climb track mode satellites
1  1        2014-02-21 20:01:02 0.000000 0.000000  00:00:00 00:00:00 0.00     0.000 0.000 0.000 0.000 0.000 0.000 0.00  0    0

HIH6130
id deviceId date       time     humidity tempC tempF
1  1        2014-02-21 20:01:02 00.00    00.00 00.00

MINIMU9V2
id deviceId date        time    heading tempC tempF xAngle yAngle zAngle xAccel yAccel zAccel xMagn  yMagn  zMagn
1  1        2014-02-21 20:01:02 000.00  00.00 00.00 00.000 00.000 00.000 00.000 00.000 00.000 00.000 00.000 00.000

RASPI
id deviceId date       time     tempC tempF
1  1        2014-02-21 20:01:02 00.00 00.00

我想选择具有deviceId = 1的表BMP085,GPS,HIH6130,MINIMU9V2和RASPI的所有匹配数据集。只应显示此设备的数据集。 此外,我想选择表格BMP085,GPS,HIH6130,MINIMU9V2和RASPI的所有匹配数据集,其日期= 2014-02-21,时间> = 20:01:00 AND< = 20:01:30

我当前的SQL语句如下所示:

SELECT t1.imei, t1.name, 
    t2.date, t2.time, t2.pressure, t2.altitude, t2.tempC, t2.tempF,
    t3.latitude, t3.longitude, t3.timeUtc, t3.timeFix, t3.altitude, t3.eps, t3.epx, t3.epv, t3.ept, t3.speed, t3.climb, t3.track, t3.mode, t3.satellites,
    t4.humidity, t4.tempC, t4.tempF,
    t5.heading, t5.tempC, t5.tempF, t5.xAngle, t5.yAngle, t5.zAngle, t5.xAccel, t5.yAccel, t5.zAccel, t5.xMagn, t5.yMagn, t5.zMagn,
    t6.tempC, t6.tempF
    FROM hab_DEVICES t1
    LEFT JOIN hab_BMP085 t2 ON t1.id = t2.deviceId
    LEFT JOIN hab_GPS t3 ON t1.id = t3.deviceId
    LEFT JOIN hab_HIH6130 t4 ON t1.id = t4.deviceId
    LEFT JOIN hab_MINIMU9V2 t5 ON t1.id = t5.deviceId
    LEFT JOIN hab_RASPI t6 ON t1.id = t6.deviceId       
    WHERE t1.id = 1
    AND t2.date = '2014-02-21'
    AND t2.date = t3.date
    AND t2.date = t4.date
    AND t2.date = t5.date
    AND t2.date = t6.date
    AND t2.time >= '20:01:00'
    AND t2.time <= '20:01:30'
    AND t2.time = t3.time
    AND t2.time = t4.time
    AND t2.time = t5.time
    AND t2.time = t6.time

结果是错误的,因为它显示一个给定时间点的多个结果而不是一个结果。 此外,表现也相当糟糕。

这是我的小提琴: http://sqlfiddle.com/#!2/639c05/1/0

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

您确定数据集结果有误吗?当你加入很多表时,你的表中可能会有重复的结果,这会使你的行显示不止一次。

检查:

SELECT t1.imei, t1.name, 
       t2.date, t2.time, t2.pressure, t2.altitude, t2.tempC, t2.tempF
FROM hab_DEVICES t1
LEFT JOIN hab_BMP085 t2 ON ( t1.id = t2.deviceId AND t1.id = 1 )
WHERE   t2.date = '2014-02-21'
    AND t2.time >= '20:01:00'
    AND t2.time <= '20:01:30'

并记下你获得的行数(也许你会发现使用SELECT count(1) AS total而不是字段有用,这将直接给你数字;; D)。完成后,添加其他表并重复。最后,您将看到哪个表负责复制您的数据。当你得到它时,你将能够知道你应该做些什么来纠正它。

关于效果,LEFT JOIN非常慢,如果您可以使用INNER JOIN,您可以快速获得结果。您还应该检查表的索引。

更新

好的,我发现了问题:你的JOIN键不仅是id,也是时间!如果您只通过id加入,则所有表将乘以所选值,但如果按id,date和time加入,则检索正确的行。将您的SQL修改为:

SELECT t1.imei, t1.name, 
        t2.date, t2.time, t2.pressure, t2.altitude, t2.tempC, t2.tempF,
        t3.latitude, t3.longitude, t3.timeUtc, t3.timeFix, t3.altitude, t3.eps, t3.epx, t3.epv, t3.ept, t3.speed, t3.climb, t3.track, t3.mode, t3.satellites,
        t4.humidity, t4.tempC, t4.tempF,
        t5.heading, t5.tempC, t5.tempF, t5.xAngle, t5.yAngle, t5.zAngle, t5.xAccel, t5.yAccel, t5.zAccel, t5.xMagn, t5.yMagn, t5.zMagn,
        t6.tempC, t6.tempF
        FROM hab_DEVICES t1
INNER JOIN hab_BMP085 t2 
ON (t1.id = t2.deviceId AND t1.id = 1 )
INNER JOIN hab_GPS t3
ON (t1.id = t3.deviceId AND t2.date = t3.date AND t2.time = t3.time AND t1.id = 1)
INNER JOIN hab_HIH6130 t4
ON (t1.id = t4.deviceId AND t2.date = t4.date AND t2.time = t4.time AND t1.id = 1)
INNER JOIN hab_MINIMU9V2 t5
ON (t1.id = t5.deviceId AND t2.date = t5.date AND t2.time = t5.time AND t1.id = 1)
INNER JOIN hab_RASPI t6
ON (t1.id = t6.deviceId AND t2.date = t6.date AND t2.time = t6.time AND t1.id = 1)  
WHERE t2.date = '2014-02-21'
AND t2.time >= '20:01:00'
AND t2.time <= '20:01:30'

检查这个小提琴:http://sqlfiddle.com/#!2/639c05/24

我认为表2中的时间是“主时间”,但你可以使用对你更有意义的东西。