加入同桌会产生太多结果

时间:2013-09-08 22:37:49

标签: mysql sql join inner-join

我的头脑在旋转,因为我在以下查询中得到了太多结果:

基于以下2个表:

P4query:

+------------+----+-----------------+--------+----------+
| Date       | Id | MeteringPointId | Reason | StatusId |
+------------+----+-----------------+--------+----------+
| 2013-08-29 | 60 |               2 | DAY    |       60 |
| 2013-08-29 | 59 |               2 | INT    |       59 |
| 2013-08-29 | 50 |               3 | DAY    |       50 |
| 2013-08-28 | 58 |               3 | DAY    |       58 |
| 2013-08-28 | 57 |               3 | INT    |       57 |
| 2013-08-28 | 56 |               2 | DAY    |       56 |
| 2013-08-28 | 55 |               2 | INT    |       55 |

和 P4Reading:

+-------------+------+---------+----------+---------------------+------+-------------+
| EnergyMeter | Id   | QueryId | Register | Time                | Unit | Value       |
+-------------+------+---------+----------+---------------------+------+-------------+
| 15524067    | 2406 |      59 | 2.8.0    | 2013-08-29 23:30:00 | WH   |       0.000 |
| 15524067    | 2609 |      59 | 1.8.0    | 2013-08-29 23:30:00 | WH   | 5959289.000 |
| 15524067    | 2243 |      59 | 2.8.0    | 2013-08-29 23:15:00 | WH   |       0.000 |
| 15524067    | 2448 |      59 | 1.8.0    | 2013-08-29 23:15:00 | WH   | 5959179.000 |

我使用以下查询在P4Reading表(同一个表)上创建JOIN,以获取前15分钟的值。这很好用,但我有很多价值观。我看起来像缺少一个联接或一个where声明,但无法掌握它。我不知道问题出在哪里。

SELECT `P4Query`.`MeteringPointId`, `table1`.`EnergyMeter`, `table1`.`Register`,
       `table1`.`Time`, `table1`.`Unit`, `table1`.`Value`,
      (`table2`.`Value` - `table1`.`Value`)/1000 as totaal
FROM P4Query, P4Reading table1
INNER JOIN P4Reading table2 ON `table1`.`Time` = (`table2`.`Time` - INTERVAL 15 minute)
WHERE (`P4Query`.`Id` = `table1`.`QueryId`)
ORDER BY `table1`.`Time` DESC;

我希望如下:

+-----------------+-------------+----------+---------------------+------+-------------+---------------+
| MeteringPointId | EnergyMeter | Register | Time                | Unit | Value       | totaal        |
+-----------------+-------------+----------+---------------------+------+-------------+---------------+
|               2 | 15524067    | 1.8.0    | 2013-08-29 23:30:00 | WH   | 5959289.000 |     0.1380000 |
|               2 | 15524067    | 2.8.0    | 2013-08-29 23:30:00 | WH   |       0.000 |     0.0000000 |
|               2 | 15524067    | 1.8.0    | 2013-08-29 23:15:00 | WH   | 5959179.000 |     0.1100000 |
|               2 | 15524067    | 2.8.0    | 2013-08-29 23:15:00 | WH   |       0.000 |     0.0000000 |

但我明白了:

+-----------------+-------------+----------+---------------------+------+-------------+---------------+
| MeteringPointId | EnergyMeter | Register | Time                | Unit | Value       | totaal        |
+-----------------+-------------+----------+---------------------+------+-------------+---------------+
|               2 | 15524067    | 2.8.0    | 2013-08-29 23:30:00 | WH   |       0.000 |  5959.4270000 |
|               2 | 15524067    | 1.8.0    | 2013-08-29 23:30:00 | WH   | 5959289.000 | -5959.2890000 |
|               2 | 15524067    | 1.8.0    | 2013-08-29 23:30:00 | WH   | 5959289.000 |     0.1380000 |
|               2 | 15524067    | 2.8.0    | 2013-08-29 23:30:00 | WH   |       0.000 |     0.0000000 |
|               2 | 15524067    | 1.8.0    | 2013-08-29 23:15:00 | WH   | 5959179.000 |     0.1100000 |
|               2 | 15524067    | 2.8.0    | 2013-08-29 23:15:00 | WH   |       0.000 |  5959.2890000 |
|               2 | 15524067    | 1.8.0    | 2013-08-29 23:15:00 | WH   | 5959179.000 | -5959.1790000 |
|               2 | 15524067    | 2.8.0    | 2013-08-29 23:15:00 | WH   |       0.000 |     0.0000000 |

我准备好了小提琴:http://sqlfiddle.com/#!2/c2bdf/1

3 个答案:

答案 0 :(得分:1)

以下是包含表别名的查询,因此更容易阅读:

SELECT pq.`MeteringPointId`, pr1.`EnergyMeter`, pr1.`Register`, pr1.`Time`, pr1.`Unit`,
       pr1.`Value`, (pr2.`Value` - pr1.`Value`)/1000 as totaal
FROM P4Query pq, P4Reading pr1 INNER JOIN
     P4Reading pr2
     ON pr1.`Time` = (pr2.`Time` - INTERVAL 15 minute)
WHERE (pq.`Id` = pr1.`QueryId`)
ORDER BY pr1.`Time` DESC;

您正在混合加入格式。您似乎错过idpr1之间pr2的条件。这可能是你想要的:

SELECT pq.`MeteringPointId`, pr1.`EnergyMeter`, pr1.`Register`, pr1.`Time`, pr1.`Unit`,
       pr1.`Value`, (pr2.`Value` - pr1.`Value`)/1000 as totaal
FROM P4Query pq join
     P4Reading pr1
     on pq.`Id` = pr1.`QueryId` join
     P4Reading pr2
     ON pq.`Id` = pr2.`QueryId` and
        pr1.`Time` = (pr2.`Time` - INTERVAL 15 minute)
ORDER BY pr1.`Time` DESC;

这会添加额外的连接条件并使连接语法保持一致。

我对这种情况有点怀疑(pr1.Time = (pr2.Time - INTERVAL 15 minute))。这需要时间值的绝对精度。在许多情况下,即使是规则间隔的时间也可能会消失几毫秒 - 导致平等失败。

答案 1 :(得分:0)

我使用的正确查询:

SELECT pq.`MeteringPointId`, pr1.`EnergyMeter`, pr1.`Register`, 
  pr1.`Time`, pr1.`Unit`, pr1.`Value`, 
 (pr2.`Value` - pr1.`Value`)/1000 as totaal
FROM P4Query pq 
JOIN P4Reading pr1 ON pq.`Id` = pr1.`QueryId` 
JOIN P4Reading pr2 ON pq.`Id` = pr2.`QueryId` 
   AND pr1.`Time` = (pr2.`Time` - INTERVAL 15 minute) 
   AND pr1.`Register` = pr2.`Register`
ORDER BY pr1.`Time` DESC;

答案 2 :(得分:0)

使用以下查询 -

SELECT distinct `table2`.`MeteringPointId`, `table1`.`EnergyMeter`, `table1`.`Register`,
   `table1`.`Time`, `table1`.`Unit`, `table1`.`Value`,
  (`table2`.`Value` - `table1`.`Value`)/1000 as totaal
  FROM P4Query table1
INNER JOIN P4Reading table2 ON `table1`.`Time` = (`table2`.`Time` - INTERVAL 15 minute)
 WHERE (`table1`.`Id` = `table2`.`QueryId`)
ORDER BY `table1`.`Time` DESC;