2

我正在构建一个 MySQL 表来为客户聚合一组特定信息。我已经使用共享键/列的记录上的简单命令成功地组装和过滤了其中的大部分内容INNER JOIN,但是数据的旋转/转置,即使是固定大小,仍然给我的查询造成一些语法混乱。该表的架构t_snapshots如下所示:

+-------------+---------------------+------+-----+---------------------+----------------+
| Field       | Type                | Null | Key | Default             | Extra          |
+-------------+---------------------+------+-----+---------------------+----------------+
| id          | int(11)             | NO   | PRI | NULL                | auto_increment | 
| value_type  | tinyint(1) unsigned | YES  |     | NULL                |                |
| ch1_id      | varchar(20)         | YES  |     | NULL                |                |
| ch1_val     | float               | NO   |     | 0                   |                |
| ch2_id      | varchar(20)         | YES  |     | NULL                |                |
| ch2_val     | float               | NO   |     | 0                   |                |
| ch3_id      | varchar(20)         | YES  |     | NULL                |                |
| ch3_val     | float               | NO   |     | 0                   |                |
| ch4_id      | varchar(20)         | YES  |     | NULL                |                |
| ch4_val     | float               | NO   |     | 0                   |                |
| timestamp   | datetime            | NO   | MUL | current_timestamp() |                |
+-------------+---------------------+------+-----+---------------------+----------------+

简单地说,我想从中选择最近更新的值t_other_data0.ch[n]发送到,并为每个唯一的发送到t_snapshots.ch[n]_val选择最近更新的 id 。与列的 n 值相关:t_id_pool.unit_idt_id_pool.channel_numt_snapshots.ch[n]_idt_id_pool.channel_numt_snapshots.ch[n]_val

t_other_data0--EDIT--:理想情况下,从源表中查找最新unit_idt_id_pool的样本数据channel_num=1,2,3,4并输出到表t_snapshots

收集最新的过程数据t_other_data0。在这种情况下,id将选择 5-8 的行,因为它们跨越所有不同value_type的最新timestamp.:

Table: t_other_data0
+----+------+------+------+------+------------+---------------------+
| id | ch1  | ch2  | ch3  | ch4  | value_type | timestamp           |
+----+------+------+------+------+------------+---------------------+
|  1 | 1.65 | 3.25 | 1.98 | 2.17 |          1 | 2021-07-22 16:26:40 |
|  2 | 3.12 | 2.33 | 6.42 | 3.22 |          2 | 2021-07-22 16:26:40 |
|  3 | 2.22 | 2.24 | 3.34 | 1.17 |          3 | 2021-07-22 16:26:40 |
|  4 | 1.52 | 1.34 |  1.9 | 2.01 |          4 | 2021-07-22 16:26:40 |
|  5 |  3.2 | 3.21 | 5.42 | 2.13 |          1 | 2021-07-22 16:26:50 |
|  6 | 1.55 | 1.92 | 4.32 | 4.12 |          2 | 2021-07-22 16:26:50 |
|  7 | 2.31 | 1.93 | 2.36 |  3.4 |          3 | 2021-07-22 16:26:50 |
|  8 | 1.78 | 2.17 | 5.62 | 2.34 |          4 | 2021-07-22 16:26:50 |
+----+------+------+------+------+------------+---------------------+

因为这些永久通道会改变它们所绑定的临时设备,所以我们使用 latest from确定unit_id每个通道的电流:channel_numunit_idt_id_pool

Table: t_id_pool
+----+---------------------+-------------+---------+
| id | timestamp           | channel_num | unit_id |
+----+---------------------+-------------+---------+
|  1 | 2021-07-22 09:39:09 |           1 | S4251   |
|  2 | 2021-07-22 09:38:09 |           2 | S3552   |
|  3 | 2021-07-22 09:38:09 |           3 | S0001   |
|  4 | 2021-07-22 09:38:09 |           4 | S1001   |
|  5 | 2021-07-22 09:39:10 |           1 | P5251   |
|  6 | 2021-07-22 09:38:10 |           2 | P4552   |
|  7 | 2021-07-22 09:38:10 |           3 | P1001   |
|  8 | 2021-07-22 09:38:10 |           4 | P2001
+----+---------------------+-------------+---------+

输出到t_snapshots

Table: t_snapshots
+-----+---------------------+------------+--------+---------+--------+---------+--------+---------+--------+---------+
| id  | timestamp           | value_type | ch1_id | ch1_val | ch2_id | ch2_val | ch3_id | ch3_val | ch4_id | ch4_val |
+-----+---------------------+------------+--------+---------+--------+---------+--------+---------+--------+---------+
| 211 | 2021-07-14 16:26:50 |          1 | P5251  |     3.2 | P4552  |    3.21 | P1001  |    5.42 | P2001  |    2.13 |
| 212 | 2021-07-14 16:26:50 |          2 | P5251  |    1.55 | P4552  |    1.92 | P1001  |    4.32 | P2001  |    4.12 |
| 213 | 2021-07-14 16:26:50 |          3 | P5251  |    2.31 | P4552  |    1.93 | P1001  |    2.36 | P2001  |     3.4 |
+-----+---------------------+------------+--------+---------+--------+---------+--------+---------+--------+---------+



 
4

1 回答 1

1

t_other_data0似乎是一个数据透视表。因此,我认为第一步是取消旋转它,然后将它与t_id_pooltable 连接以获取最新的unit_id,然后再次重新旋转它。也许这样的查询可以工作:

SELECT 0 id, tod.timestamp, value_type,
       MAX(case when channel_num=1 THEN unit_id else 0 END) AS ch1_id,
       SUM(case when channel_num=1 then chan_val else 0 END) as ch1_val,
       MAX(CASE WHEN channel_num=2 THEN unit_id ELSE 0 END) AS ch2_id,
       SUM(CASE WHEN channel_num=2 THEN chan_val ELSE 0 END) AS ch2_val,
       MAX(CASE WHEN channel_num=3 THEN unit_id ELSE 0 END) AS ch3_id,
       SUM(CASE WHEN channel_num=3 THEN chan_val ELSE 0 END) AS ch3_val,
       MAX(CASE WHEN channel_num=4 THEN unit_id ELSE 0 END) AS ch4_id,
       SUM(CASE WHEN channel_num=4 THEN chan_val ELSE 0 END) AS ch4_val
FROM   (SELECT value_type, ch1 AS chan_val, 1 AS chan_num, timestamp
        FROM   (SELECT *, Row_number() OVER (partition BY value_type ORDER BY id DESC) rn
                FROM t_other_data0) AS A
        WHERE  rn = 1 UNION ALL
        SELECT value_type, ch2, 2,
               timestamp
        FROM   (SELECT *, Row_number() OVER (partition BY value_type ORDER BY id DESC) rn
                FROM t_other_data0) AS A
        WHERE  rn = 1 UNION ALL
        SELECT value_type, ch3, 3,
               timestamp
        FROM   (SELECT *, Row_number() OVER (partition BY value_type ORDER BY id DESC) rn
                FROM t_other_data0) AS A
        WHERE  rn = 1 UNION ALL
        SELECT value_type, ch4, 4,
               timestamp
        FROM   (SELECT *, Row_number() OVER (partition BY value_type ORDER BY id DESC) rn
                FROM t_other_data0) AS A
        WHERE  rn = 1) AS tod
       JOIN (SELECT id, timestamp, channel_num, unit_id, 
                    Row_number() OVER (partition BY channel_num ORDER BY timestamp DESC) rn
             FROM t_id_pool) AS tip
         ON tod.chan_num = tip.channel_num AND tip.rn = 1
    GROUP BY tod.timestamp, value_type;

此处使用的功能之一是为最新和时间戳ROW_NUMBER()分配行号。至于表,我正在使用,并且在列之后总共有 4 个查询。我根据我选择的列给他们每个人分配一个硬编码。1value_typechannel_numbert_other_data0UNION ALLch1, ch2, ch3 & ch4chan_num

我不确定id要填充什么的列,但我假设由于查询的主要目的是INSERT进入另一个表,那么该id列可能是自动递增的。

不幸的是 dbfiddle.uk 从昨天开始就不能使用了,所以这里的小提琴是用于 MySQL v8.0 而不是 MariaDB 10.3。https://www.db-fiddle.com/f/xf1VmfYMbnGcabJS7dS6A1/1。小提琴中的结果将有一个额外的行t_other_data.id=8(@danblack 在评论中提到)并且不会包括id=4,因为您的条件是"Gather latest process data from t_other_table0"。但是从您的预期输出来看,您似乎没有包含id=4,所以您的描述中可能有一些错误。

于 2021-07-23T03:13:37.623 回答