【问题标题】:Optimize query for multiple columns extracted from the same table优化从同一个表中提取的多个列的查询
【发布时间】:2011-05-09 14:20:18
【问题描述】:

这是another question here on SO的后续。

我有这两个数据库表(更多表省略):

acquisitions (acq)
    id {PK}
    id_cu {FK}
    datetime
    { Unique Constraint: id_cu - datetime }

data
    id {PK}
    id_acq {FK acquisitions}
    id_meas
    id_elab
    value

所有可能的iddatetime都被全部编入索引。

当然,我会更改我需要以这种方式提取数据的数据库结构:

  • 按日期时间分组的行
  • 每一列对应于所选data.value 组合的data.value。 (见帖子底部的注释)
  • 如果某些列的数据在日期时间中丢失但其他列存在,则允许空单元格

我当前的查询是这样构建的(参见SO question):

SELECT datetime, MAX(v1) AS v1, MAX(v2) AS v2, MAX(v3) AS v3 FROM (

SELECT acq.datetime AS datetime, data.value AS v1, NULL AS v2, NULL AS v3 
FROM acq INNER JOIN data ON acq.id = data.id_acq
WHERE acq.id_cu = 3 AND data.id_meas = 2 AND data.id_elab = 1

UNION

SELECT acq.datetime AS datetime, NULL AS v1, data.value AS v2, NULL AS v3 
FROM acq INNER JOIN data ON acq.id = data.id_acq
WHERE acq.id_cu = 5 AND data.id_meas = 4 AND data.id_elab = 6

UNION

SELECT acq.datetime AS datetime, NULL AS v1, NULL AS v2, data.value AS v3 
FROM acq INNER JOIN data ON acq.id = data.id_acq
WHERE acq.id_cu = 7 AND data.id_meas = 9 AND data.id_elab = 8

) AS T
WHERE datetime >= "2011-03-01 00:00:00" AND datetime <= "2011-04-30 23:59:59"
GROUP BY datetime

这里只检索 3 列,但正如我所说,列通常超过 50。

它完美无瑕,但我想知道它是否可以在速度上进行优化。

这是上面查询的 MySQL EXPLAIN EXTENDED

+----+--------------+--------------+------+------------------------------------------------+-----------------------+---------+------------------------+-------+----------+----------------------------------------------+
| id | select_type  | table        | type | possible_keys                                  | key                   | key_len | ref                    | rows  | filtered | Extra                                        |
+----+--------------+--------------+------+------------------------------------------------+-----------------------+---------+------------------------+-------+----------+----------------------------------------------+
|  1 | PRIMARY      | <derived2>   | ALL  | NULL                                           | NULL                  | NULL    | NULL                   | 82466 |   100.00 | Using where; Using temporary; Using filesort |
|  2 | DERIVED      | acquisitions | ref  | PRIMARY,id_cu,ix_acquisitions_id_cu            | id_cu                 | 4       |                        | 18011 |   100.00 |                                              |
|  2 | DERIVED      | data         | ref  | ix_data_id_meas,ix_data_id_acq,ix_data_id_elab | ix_data_id_acq        | 4       | sensor.acquisitions.id |     9 |   100.00 | Using where                                  |
|  3 | UNION        | acquisitions | ref  | PRIMARY,id_cu,ix_acquisitions_id_cu            | ix_acquisitions_id_cu | 4       |                        | 20864 |   100.00 |                                              |
|  3 | UNION        | data         | ref  | ix_data_id_meas,ix_data_id_acq,ix_data_id_elab | ix_data_id_acq        | 4       | sensor.acquisitions.id |     9 |   100.00 | Using where                                  |
|  4 | UNION        | acquisitions | ref  | PRIMARY,id_cu,ix_acquisitions_id_cu            | id_cu                 | 4       |                        | 31848 |   100.00 |                                              |
|  4 | UNION        | data         | ref  | ix_data_id_meas,ix_data_id_acq,ix_data_id_elab | ix_data_id_acq        | 4       | sensor.acquisitions.id |     9 |   100.00 | Using where                                  |
| NULL | UNION RESULT | <union2,3,4> | ALL  | NULL                                           | NULL                  | NULL    | NULL                   |  NULL |     NULL |                                              |
+----+--------------+--------------+------+------------------------------------------------+-----------------------+---------+------------------------+-------+----------+----------------------------------------------+
8 rows in set, 1 warning (8.24 sec)

目前(edit:今天检查)390k 次采集和 920 万个数据值(并且还在增长)提取一个包含 59 列的表大约需要 10 分钟。我知道以前的软件提取数据最多需要 1 小时。

感谢您耐心阅读到这里 :)


更新

在丹尼斯回答后,我尝试了他的更改 1. 和 2.,这是新查询的结果:

SELECT datetime, MAX(v1) AS v1, MAX(v2) AS v2, MAX(v3) AS v3 FROM (

SELECT acq.datetime AS datetime, data.value AS v1, NULL AS v2, NULL AS v3 
FROM acq INNER JOIN data ON acq.id = data.id_acq
WHERE acq.id_cu = 3 AND data.id_meas = 2 AND data.id_elab = 1
AND datetime >= "2011-03-01 00:00:00" AND datetime <= "2011-04-30 23:59:59"

UNION ALL

SELECT acq.datetime AS datetime, NULL AS v1, data.value AS v2, NULL AS v3 
FROM acq INNER JOIN data ON acq.id = data.id_acq
WHERE acq.id_cu = 5 AND data.id_meas = 4 AND data.id_elab = 6
AND datetime >= "2011-03-01 00:00:00" AND datetime <= "2011-04-30 23:59:59"

UNION ALL

SELECT acq.datetime AS datetime, NULL AS v1, NULL AS v2, data.value AS v3 
FROM acq INNER JOIN data ON acq.id = data.id_acq
WHERE acq.id_cu = 7 AND data.id_meas = 9 AND data.id_elab = 8
AND datetime >= "2011-03-01 00:00:00" AND datetime <= "2011-04-30 23:59:59"

) AS T GROUP BY datetime

这里是新的EXPLAIN EXTENDED

+----+--------------+--------------+-------+--------------------------------------------------------------+----------------+---------+------------------------+-------+----------+---------------------------------+
| id | select_type  | table        | type  | possible_keys                                                | key            | key_len | ref                    | rows  | filtered | Extra                           |
+----+--------------+--------------+-------+--------------------------------------------------------------+----------------+---------+------------------------+-------+----------+---------------------------------+
|  1 | PRIMARY      | <derived2>   | ALL   | NULL                                                         | NULL           | NULL    | NULL                   | 51997 |   100.00 | Using temporary; Using filesort |
|  2 | DERIVED      | acquisitions | range | PRIMARY,id_cu,ix_acquisitions_datetime,ix_acquisitions_id_cu | id_cu          | 12      | NULL                   | 14827 |   100.00 | Using where                     |
|  2 | DERIVED      | data         | ref   | ix_data_id_meas,ix_data_id_acq,ix_data_id_elab               | ix_data_id_acq | 4       | sensor.acquisitions.id |     9 |   100.00 | Using where                     |
|  3 | UNION        | acquisitions | range | PRIMARY,id_cu,ix_acquisitions_datetime,ix_acquisitions_id_cu | id_cu          | 12      | NULL                   | 18663 |   100.00 | Using where                     |
|  3 | UNION        | data         | ref   | ix_data_id_meas,ix_data_id_acq,ix_data_id_elab               | ix_data_id_acq | 4       | sensor.acquisitions.id |     9 |   100.00 | Using where                     |
|  4 | UNION        | acquisitions | range | PRIMARY,id_cu,ix_acquisitions_datetime,ix_acquisitions_id_cu | id_cu          | 12      | NULL                   | 13260 |   100.00 | Using where                     |
|  4 | UNION        | data         | ref   | ix_data_id_meas,ix_data_id_acq,ix_data_id_elab               | ix_data_id_acq | 4       | sensor.acquisitions.id |     9 |   100.00 | Using where                     |
| NULL | UNION RESULT | <union2,3,4> | ALL   | NULL                                                         | NULL           | NULL    | NULL                   |  NULL |     NULL |                                 |
+----+--------------+--------------+-------+--------------------------------------------------------------+----------------+---------+------------------------+-------+----------+---------------------------------+
8 rows in set, 1 warning (3.01 sec)

毫无疑问在性能上获得了不错的收益


更新(2)

这个来加点3.

EXPLAIN EXTENDED SELECT datetime, MAX(v1) AS v1, MAX(v2) AS v2, MAX(v3) AS v3 FROM (

SELECT acquisitions.datetime AS datetime, MAX(data.value) AS v1, NULL AS v2, NULL AS v3 
FROM acquisitions INNER JOIN data ON acquisitions.id = data.id_acq
WHERE acquisitions.id_cu = 1 AND data.id_meas = 1 AND data.id_elab = 2
AND datetime >= "2011-03-01 00:00:00" AND datetime <= "2011-04-30 23:59:59"
GROUP BY datetime

UNION ALL

SELECT acquisitions.datetime AS datetime, NULL AS v1, MAX(data.value) AS v2, NULL AS v3 
FROM acquisitions INNER JOIN data ON acquisitions.id = data.id_acq
WHERE acquisitions.id_cu = 4 AND data.id_meas = 1 AND data.id_elab = 2
AND datetime >= "2011-03-01 00:00:00" AND datetime <= "2011-04-30 23:59:59"
GROUP BY datetime

UNION ALL

SELECT acquisitions.datetime AS datetime, NULL AS v1, NULL AS v2, MAX(data.value) AS v3 
FROM acquisitions INNER JOIN data ON acquisitions.id = data.id_acq
WHERE acquisitions.id_cu = 8 AND data.id_meas = 1 AND data.id_elab = 2
AND datetime >= "2011-03-01 00:00:00" AND datetime <= "2011-04-30 23:59:59"
GROUP BY datetime

) AS T GROUP BY datetime;

这是EXPLAIN EXTENDED的结果

+----+--------------+--------------+-------+--------------------------------------------------------------+----------------+---------+------------------------+-------+----------+---------------------------------+
| id | select_type  | table        | type  | possible_keys                                                | key            | key_len | ref                    | rows  | filtered | Extra                           |
+----+--------------+--------------+-------+--------------------------------------------------------------+----------------+---------+------------------------+-------+----------+---------------------------------+
|  1 | PRIMARY      | <derived2>   | ALL   | NULL                                                         | NULL           | NULL    | NULL                   | 51997 |   100.00 | Using temporary; Using filesort |
|  2 | DERIVED      | acquisitions | range | PRIMARY,id_cu,ix_acquisitions_datetime,ix_acquisitions_id_cu | id_cu          | 12      | NULL                   | 14827 |   100.00 | Using where                     |
|  2 | DERIVED      | data         | ref   | ix_data_id_meas,ix_data_id_acq,ix_data_id_elab               | ix_data_id_acq | 4       | sensor.acquisitions.id |     9 |   100.00 | Using where                     |
|  3 | UNION        | acquisitions | range | PRIMARY,id_cu,ix_acquisitions_datetime,ix_acquisitions_id_cu | id_cu          | 12      | NULL                   | 18663 |   100.00 | Using where                     |
|  3 | UNION        | data         | ref   | ix_data_id_meas,ix_data_id_acq,ix_data_id_elab               | ix_data_id_acq | 4       | sensor.acquisitions.id |     9 |   100.00 | Using where                     |
|  4 | UNION        | acquisitions | range | PRIMARY,id_cu,ix_acquisitions_datetime,ix_acquisitions_id_cu | id_cu          | 12      | NULL                   | 13260 |   100.00 | Using where                     |
|  4 | UNION        | data         | ref   | ix_data_id_meas,ix_data_id_acq,ix_data_id_elab               | ix_data_id_acq | 4       | sensor.acquisitions.id |     9 |   100.00 | Using where                     |
| NULL | UNION RESULT | <union2,3,4> | ALL   | NULL                                                         | NULL           | NULL    | NULL                   |  NULL |     NULL |                                 |
+----+--------------+--------------+-------+--------------------------------------------------------------+----------------+---------+------------------------+-------+----------+---------------------------------+
8 rows in set, 1 warning (3.06 sec)

稍微慢一点,这应该受益于大量的coulmns吗?我试试看……


更新(3)

我尝试了使用和不使用MAX(data.value)... GROUP BY datetime,并且在 60 列查询中我得到了更好的结果使用。结果因尝试而异,这是其中之一。

  • 原查询9m12.144s
  • 与丹尼斯的1.2. 4m6.597s
  • 与丹尼斯的1.2.3. 4m0.210s

所需时间减少了大约 57%。


更新(4)

我尝试了 Andiry 解决方案,但它比 Denis 优化慢。

在 3 个组合/列上测试:

  • 未优化:1m3s
  • Denis 的优化:1.7s
  • Andiry 的CASE:9.3s

我还测试了 12 个组合/列:

  • 未优化:未经测试
  • Denis 的优化:3.6s
  • Andiry 的CASE:13.7s

此外,Andiry 的解决方案还提取没有任何选定组合的数据但其他组合存在的获取日期。

想象一下,控制单元 1 在 :00 和 :30 每 30 分钟获取一次数据,而控制单元 2 在 :15 和 :45:我将用 NULL 填充空行的行数加倍。


注意:

这都是关于传感器系统的:有几个控制单元(每个id_cu一个),每个都有许多传感器

单个传感器由一对id_cu / id_meas 识别,并为每个测量发送不同的详细说明,例如MIN (id_elab=1)、MAX (id_elab=2)、AVERAGE (id_elab=3) , INSTANT (id_elab=...) 等,每个id_elab 一个。

用户可以随意挑选他想要的许多细节,比如:

  • 结果列的控制单元 #1 的传感器 #3 的平均值 (3) 所以 id_cu=1 / id_meas=3 / id_elab=3
  • 控制单元 #1 的传感器 #5 的平均值 (3) 用于结果列,因此 id_cu=1 / id_meas=5 / id_elab=3
  • 另一列的控制单元#4 的传感器#2 的最小值 (1) 所以id_cu=4 / id_meas=2 / id_elab=1
  • (输入任何有效的id_cu, id_meas, id_elab组合)
  • ...

等等,多达几十种选择……

这是部分 DDL(不相关的表除外):

CREATE TABLE acquisitions (
    id INTEGER NOT NULL AUTO_INCREMENT, 
    id_cu INTEGER NOT NULL, 
    datetime DATETIME NOT NULL, 
    PRIMARY KEY (id), 
    UNIQUE (id_cu, datetime), 
    FOREIGN KEY(id_cu) REFERENCES ctrl_units (id) ON DELETE CASCADE
)

CREATE TABLE data (
    id INTEGER NOT NULL AUTO_INCREMENT, 
    id_acq INTEGER NOT NULL, 
    id_meas INTEGER NOT NULL, 
    id_elab INTEGER NOT NULL, 
    value FLOAT, 
    PRIMARY KEY (id), 
    FOREIGN KEY(id_acq) REFERENCES acquisitions (id) ON DELETE CASCADE
)

CREATE TABLE ctrl_units (
    id INTEGER NOT NULL, 
    name VARCHAR(40) NOT NULL, 
    PRIMARY KEY (id)
)

CREATE TABLE sensors (
    id_cu INTEGER NOT NULL, 
    id_meas INTEGER NOT NULL, 
    id_elab INTEGER NOT NULL, 
    name VARCHAR(40) NOT NULL, 
    `desc` VARCHAR(80), 
    PRIMARY KEY (id_cu, id_meas), 
    FOREIGN KEY(id_cu) REFERENCES ctrl_units (id) ON DELETE CASCADE
)

【问题讨论】:

  • 注意让它更清楚一点。仍然一个简单的测试用例/数据会在提高答案的质量方面产生奇迹(包括 DDL 的额外分数)。例如,另一个混淆点是当您提到 MIN、MAX、AVERAGE、INSTANT 时,您指的是 id_elabs(代码 2 表示 AVERAGE,代码 1 表示 MIN,等等)?如果是,那么所需的结果将完全不同,并且 您不需要 SQL(!) 中的任何聚合。此外,使用适当的 composite 索引,您拥有的查询可以更快地运行数量级。
  • @Unreason:我试图在注释中更好地解释id_elab,是的,MIN、MAX 指的是不同的 id,我也会尽快发布 DDL(现在不在服务器上)。跨度>
  • @Unreason:也添加了 DDL,我找到了找回它的方法。
  • @neurino:你能看看我的解决方案吗?这也是我试图向 Unreason 解释的内容,但似乎我并不总是擅长解释事情。 :)
  • @Andiry:我肯定会在明天早上(现在是晚上 10:45)对数据进行测试,谢谢

标签: mysql sql query-optimization


【解决方案1】:

主要存在三个问题:

  1. 使用联合所有,而不是联合。您正在分组并获取最小值/最大值,因此引入排序步骤以删除重复行是没有意义的。

  2. where 子句可以放在每个联合子语句中:

    select ...
    from (
    select ... from ...  where ...
    union all
    select ... from ...  where ...
    union all
    ...
    )
    group by ...
    

    按照您编写的方式,它首先获取所有行,将它们全部附加,最后过滤您需要的行。在联合子语句中注入 where 子句将使其仅获取您需要的行,最后将它们全部追加。

  3. 按照同样的思路,预先聚合聚合:

    select ..., max(foo) as foo
    from (
    select ..., max(foo) as foo from ...  where ... group by ...
    union all
    select ..., max(foo) as foo from ...  where ... group by ...
    union all
    ...
    )
    group by ...
    

    优化器将更好地利用现有索引,您最终只会追加几行,而不是几百万行。

【讨论】:

  • @Denis:谢谢,我应用了你的点 1.2. 但不明白点 3. 我应该把 MAX 只作为 MAX(data.value) 还是 NULL ?为什么?我用新的EXPLAINresult 更新了问题
  • 是的,max(data.value) 在适当的地方,否则为 null。
  • @Denis:谢谢,这也有帮助,我重新更新了问题并进行了全面更改。
  • 可能还有最后一个你可以做的。也在内部查询中折腾分组(我会相应地更新我的答案)。您当前的查询计划使它看起来没有聚合。
  • @Denis:实际上使用MAX(data.value) 返回了一行而不是数百行,这有问题。
【解决方案2】:
SELECT
  acq.datetime,
  MAX(CASE WHEN acq.id_cu = 2 AND data.id_meas = 2 AND data.id_elab = 1 THEN data.value END) AS v1,
  MAX(CASE WHEN acq.id_cu = 5 AND data.id_meas = 4 AND data.id_elab = 6 THEN data.value END) AS v2,
  MAX(CASE WHEN acq.id_cu = 7 AND data.id_meas = 9 AND data.id_elab = 8 THEN data.value END) AS v3
FROM acq
  INNER JOIN data acq.id = data.id_acq
WHERE datetime >= 2011-03-01 00:00:00 AND datetime <= 2011-04-30 23:59:59
GROUP BY acq.datetime

这可能看起来与您的原始查询大致相同,但主要区别在于逻辑上它只扫描表一次,而不是使用 UNION 扫描表三次或多次。

【讨论】:

  • 抱歉,我的示例具有误导性:data.id_meas = 1 AND data.id_elab = 2 始终相同,我更新了示例查询以更好地解释。无论如何,它显然是有问题的:每个列对应的 data.value 用于选定的 acq.id_cu - data.id_meas - data.id_elab 组合
  • @neurino:要点:我确实应该更多地关注整个描述。请查看我更新的解决方案。
  • @Andriy M,我明白了你的意思,但这仍然不是最好的(正确的)方法(我的也不是)。所以是的,我的和你的都将进行一次扫描,但尚不清楚你的是否是一种改进 - 将更多条件放入 CASE 可能看起来更有效,但你实际上是通过从 WHERE 中删除它们来隐藏查询计划器(并且隐藏了更多的访问路径选择;当然,规划器并不完美,因此通过隐藏它可能会获得更好的性能,或者因为没有可用的索引,所以它是相同的)。
  • @Unreason:我并不是说这是对您的解决方案在性能方面的改进。它比我以前的解决方案(与您的解决方案相同)更正确,我错误地认为 acq.id_cu 是应该在 CASE 中使用的唯一不同标准。另一方面,我认为这种方法总体上没有任何问题。你和我都知道这是 OP 方法的正确(即使不是唯一的)替代方法(用他们自己的话来说,'工作完美')。我们只是对过滤部分错了。现在,我明白了,我们不是。
  • @Andriy M,完全同意。除了对唯一方法的评论(即使从 SQL 的正确性来看,这也可能是正确的)。然而,这里隐藏着一个巨大的胜利:这里的问题是 OP 正在做一系列简单的选择(参见相关问题 - stackoverflow.com/questions/4469872/…),仅在 150 万条记录上(取决于结果集的选择性/基数)不应该,使用适当的索引(涵盖所有条件的复合索引)需要大量时间。这应该是 OP 的首要任务,并将带来巨大的性能优势。
【解决方案3】:

基本上,我认为使用单个 SELECT 和 CASE 处理条件会获得更好的结果。无论如何,您可能想要进行基准测试和比较...

SELECT acq.datetime AS datetime, 
       MAX(
           CASE acq.id_cu
           WHEN 1 THEN data.value
           END 
       ) as v1,
       MAX(
           CASE acq.id_cu
           WHEN 4 THEN data.value
           END 
       ) as v2,
       MAX(
           CASE acq.id_cu
           WHEN 8 THEN data.value
           END 
       ) as v3
FROM 
       acq INNER JOIN data ON acq.id = data.id_acq
WHERE 
       data.id_meas = 1 AND data.id_elab = 2 AND
       datetime BETWEEN "2011-03-01 00:00:00" AND "2011-04-30 23:59:59"

这应该进行干净的范围扫描。 此外,复合索引还可以做更多事情。

最后,例如使用 GROUP BY 有什么问题吗

SELECT data.id_means, acq.datetime AS datetime, MAX(data.value)
FROM 
       acq INNER JOIN data ON acq.id = data.id_acq
WHERE 
       data.id_elab = 2 AND
       datetime BETWEEN "2011-03-01 00:00:00" AND "2011-04-30 23:59:59" AND
       data.id_means IN (1,4,8)
GROUP BY
       data.id_means

这是最简单的形式(也是最灵活的)——即使没有为您将行转置为列(对于 data.id_meas 的不同值)。但这会让您最好地了解预期的性能以及哪些索引应该对查询最有用。

编辑: 要获得 *acq.id_cu - data.id_meas - data.id_elab 组合*的最大 data.value,您应该能够简单地使用

SELECT 
       acq.id_cu, data.id_meas, data.id_elab, acq.datetime AS datetime, MAX(data.value)
FROM 
       acq INNER JOIN data ON acq.id = data.id_acq
WHERE 
       data.id_elab = 2 AND
       datetime BETWEEN "2011-03-01 00:00:00" AND "2011-04-30 23:59:59" AND
       data.id_means IN (1,4,8)
GROUP BY
       acq.id_cu, data.id_meas, data.id_elab, acq.datetime

将为acq.id_cu, data.id_meas, data.id_elab, acq.datetime 的所有组合提供 max(data.value) ( 使用 where 的值对其进行过滤 - 调整影响结果的位置)。 对于没有行的组合,这不会显示 NULL,但如果这对您来说是正确的方向,则有一种解决方法。 GROUP BY 也决定了排序,所以改变 group by 中列的顺序。

如果我的回答仍然没有抓住要点,一些示例数据/测试用例会很有用。

你的例子中令人困惑的部分是当你说

每一列对应的data.value 对于选定的 acq.id_cu - data.id_meas - data.id_elab 组合。

但是当您在示例查询中选择数据时,您会将它们直接选择到仅具有日期时间分组的列中,因此如果它确实是值的组合,则无法识别哪一行对应于哪个组合(可以有多行特定日期)。如果它不是您想要过滤/分组的所有值的组合,但确定 max 值的分组条件直接取决于日期时间。

【讨论】:

  • 可能,我不理解你的例子或你的观点,如果我不够清楚,我很抱歉,但我的意思是元组 id_cu - id_meas - id_elab 每列都不同。
  • 首先尝试正确命名。元组(~row)由属性(~columns)组成。所以说“每列的元组都不同”并不能真正计算。无论如何,如果我没有犯语法错误,我的答案中的第一个查询应该与问题/答案/更新中的查询等效(返回相同的结果集)。
  • 不合理,我的名字是对的,元组是你写的(1, 4, 8),那不是row。我编辑了我的示例(是的,这是一个示例,不是真实且唯一的查询),因此您可能会更好地理解我的情况,请随时采用您的代码,以便我可以理解您的问题,谢谢.
  • @Unreason:尽可能清楚:在问题中我写道:每个列对应的 data.value 用于选定的 acq.id_cu - data.id_meas - data.id_elab 组合 i> 我认为这已经足够清楚了。谢谢(ps,请原谅我,在上面的评论中我写了 question 但它是 answer
  • @Unreason:我不知道它是怎么发生的,但我完全错过了你的答案并发布了完全相同的解决方案!对不起,我已经删除了我的答案。我认为您只需要坚持使用您的第一个变体并将搜索案例转换为搜索案例,根据 OP 的示例写出 acq.id_cudata.id_measdata.id_elab 的完整过滤器。
猜你喜欢
  • 1970-01-01
  • 2011-04-23
  • 1970-01-01
  • 2019-08-08
  • 2010-09-17
  • 2021-12-19
  • 2020-02-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多