在CubeJS中实现DISTINCT ON

问题描述

我有一个这样的Postgres表,其中包含设备ID,时间戳和当时设备的状态:

dev_id  | timestamp             | status
----------------------------------------
1       | 2020-08-06 23:00:00   | 1
2       | 2020-08-06 23:00:00   | 0
3       | 2020-08-06 23:00:00   | 1
2       | 2020-08-06 23:05:00   | 1
3       | 2020-08-06 23:05:00   | 0
1       | 2020-08-06 23:10:00   | 0

我想在各自的最新时间戳中查看有多少设备正在运行以及有多少设备没有运行。在Postgres中,我可以使用disTINCT ON并编写如下查询

SELECT status,COUNT(status) 
FROM
  (
    SELECT disTINCT ON (dev_id) dev_id,timestamp,status 
    FROM
      sample_metrics_data 
    ORDER BY
      dev_id,timestamp DESC
  ) sub 
GROUP BY status; 

这将导致:

value   | count
---------------
0       | 2
1       | 1

(2个设备#1和#3的状态为0,而1#2的状态为1。) 如何在CubeJS中创建类似的内容?是否支持disTINCT ON,如果不支持,该怎么解决

或者,可以使用内部联接编写查询

SELECT status,Count(status)
FROM   sample_metrics_data
       JOIN (SELECT dev_id         id,Max(timestamp) ts
             FROM   sample_metrics_data
             GROUP  BY dev_id) max_ts
         ON timestamp = max_ts.ts
            AND dev_id = max_ts.id
GROUP BY status; 

我需要进行内部联接,但是似乎只有LEFT JOIN可用。

解决方法

对于您而言,如果您需要绘制在线设备数量的图表,则典型的解决方案是

  1. 构建一个多维数据集,其中将包含有关在线设备数量变化的数据。
  2. 使用rollingWindow创建度量

例如,我按照您的问题制作了一张桌子

sample_metrics table structure

并创建此多维数据集

cube(`SampleMetricsData`,{
  sql: "SELECT *,device_status - COALESCE(LAG(device_status) OVER (PARTITION BY id ORDER BY timemark ASC),0) as rolling_status FROM ab_api_test.sample_metrics ORDER BY `sample_metrics`.`timemark` DESC",measures: { 
    rollingStatusTotal: {
      sql: `rolling_status`,type: `sum`,rollingWindow: { 
        trailing: `unbounded`,},dimensions: {
    id: {
      sql: `id`,type: `number`,primaryKey: true
    },timemark: {
      sql: `timemark`,type: `time`
    },}
});

在此多维数据集上,您可以通过此查询查看在线设备图表

{"measures":["SampleMetricsData.rollingStatusTotal"],"timeDimensions":[{"dimension":"SampleMetricsData.timemark","granularity":"hour","dateRange":"This month"}],"order":{},"dimensions":[],"filters":[]}

可能您应该看到此tutorial,看起来与您的任务类似。还有一个related question is here

注意

您还可以编写类似的查询,以根据数据创建多维数据集。 但这不是最佳做法

select * from (
     SELECT DISTINCT ON (dev_id) dev_id,timestamp,status
     FROM
       sample_metrics_data
     ORDER BY
       dev_id,timestamp DESC
) as sample_metrics