Используйте оператор WHERE IN с ОГРАНИЧЕНИЕМ DESC 1 для каждого идентификатора

#sql #node.js #cassandra #greatest-n-per-group #cql

#sql #node.js #кассандра #наибольшее число пользователей на группу #cql

Вопрос:

У меня есть таблица в 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, поскольку я не хочу извлекать данные для всех арендаторов, а только для выбранных.

Комментарии:

1. howtoprogram.xyz/2017/02/18/ использование-group-apache-cassandara

2. Я думаю, вам нужно выбрать все идентификаторы клиентов и максимальные значения (назовем это max_table ), а затем присоединиться к вашей основной таблице where max_table.tenantId = main_table.tenantId and max_table.timestamp = main_table.timestamp . Простое использование max() and group by не будет работать, поскольку вас также интересует usage значение, следовательно, более сложное соединение. Вероятно, есть более эффективный способ, но это сработает.

Ответ №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

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

Преимущества этого решения :

  1. Использование запросов «В предложении» является антишаблоном в Cassandra, поскольку вы пытаетесь получить доступ к нескольким разделам в одном запросе. В некоторых случаях это может привести к таймауту.
  2. Это решает задачу без сложности.