【问题标题】:Use WHERE IN operator with DESC LIMIT 1 for Each ID对每个 ID 使用 DESC LIMIT 1 的 WHERE IN 运算符
【发布时间】:2021-01-07 22:55:34
【问题描述】:

我在 Cassandra 中有一个表,其中存储了租户最近更新的详细信息。 有一个时间戳字段可以更新使用情况。我需要为每个租户找到最后更新的详细信息。 所以,考虑表结构是这样的:

现在,我需要这样的输出:

我写过这样的查询:

aQueries = ['t1','t2','t3'];
const query = `SELECT * 
  FROM system_log_stats.keyspaces_sizes
  WHERE keyspace_name IN ? ORDER BY  timestamp_sec DESC LIMIT 1`;
const res = await client.execute(query, [aQueries], { prepare: true});

但上面的查询只返回 1 个结果。

请注意,我必须使用 where IN 子句,因为我不想获取所有租户,而只想获取选定的租户。

【问题讨论】:

  • 我认为您需要子选择所有租户 ID 和最大值(我们称之为max_table),然后加入您的主表max_table.tenantId = main_table.tenantId and max_table.timestamp = main_table.timestamp。简单地使用max()group by 是行不通的,因为您也对usage 值感兴趣,因此连接更复杂。可能有一种更有效的方法,但这会奏效。

标签: sql node.js cassandra greatest-n-per-group cql


【解决方案1】:

在 Cassandra 中,LIMIT 1 只会返回整个结果集中 1 行的结果。

Cassandra 还提供了PER PARTITION LIMIT 1,它从结果集中的每个分区返回 1 行。

https://cassandra.apache.org/doc/latest/cql/dml.html#limiting-results

在您的示例中,您可以执行类似的操作

SELECT * 
  FROM system_log_stats.keyspaces_sizes
  WHERE keyspace_name IN ? ORDER BY  timestamp_sec DESC PER PARTITION LIMIT 1

(虽然我不确定 ORDER BY 是否可以同时使用。)

【讨论】:

    【解决方案2】:

    干净的解决方案是在循环中多次使用查询。您可以在循环中查询以下 Tenanat Id 列表

    select * from 
    table where tenantd Id =?
    ORDER BY  timestamp_sec DESC LIMIT 1
    

    此解决方案的优点:

    1. 在 Cassandra 中使用“IN 子句”查询是反模式,因为您试图在同一查询中访问多个分区。在某些情况下,这可能会导致超时。
    2. 它解决了目标而不复杂。

    【讨论】:

      猜你喜欢
      • 2020-01-13
      • 1970-01-01
      • 2014-11-30
      • 1970-01-01
      • 2011-01-10
      • 1970-01-01
      • 1970-01-01
      • 2016-04-23
      • 1970-01-01
      相关资源
      最近更新 更多