如何在 cube.js 中实现子查询

Posted

技术标签:

【中文标题】如何在 cube.js 中实现子查询【英文标题】:How to implement subqueries in cube.js 【发布时间】:2021-05-01 06:21:09 【问题描述】:

我正在努力了解如何在 cube.js 架构中表示以下类型的 postgres SQL 查询:

SELECT
CASE
    WHEN COUNT(tpp.net_total_amount) > 0 THEN
        SUM(tpp.net_total_amount) / COUNT(tpp.net_total_amount)
    ELSE
        NULL
    END AS average_spend_per_customer
FROM
    (
        SELECT
            SUM(ts.total_amount) AS net_total_amount
        FROM
            postgres.transactions AS ts
        WHERE
            ts.transaction_date >= '2020-11-01' AND
            ts.transaction_date < '2020-12-01'
        GROUP BY
            ts.customer_id,
            ts.event_id
    ) AS tpp
;

我觉得预聚合可能是我所追求的,但在研究它们之后似乎并非如此。我可以使用以下架构获得每个客户每个事件的总花费列表:

cube(`TransactionTotalAmountByCustomerAndEvent`, 
  sql: `SELECT * FROM postgres.transactions`,

  joins: 

  ,

  measures: 
    sum: 
      sql: `SUM(total_amount)`,
      type: `number`
    
  ,

  dimensions: 
    eventId: 
      sql: `event_id`,
      type: `string`
    ,

    customerId: 
      sql: `customer_id`,
      type: `string`
    ,

    transactionDate: 
      sql: `transaction_date`,
      type: `time`
    
  ,

  preAggregations: 
    customerAndEvent: 
      type: `rollup`,
      measureReferences: [sum],
      dimensionReferences: [customerId, eventId]
    
  
);

但这实际上只是给了我按客户和事件分组的内部 SELECT 语句的输出。如何查询多维数据集以获得我所追求的每个事件的平均客户支出?

【问题讨论】:

【参考方案1】:

您可能会发现将数据集建模为两个不同的立方体CustomersTransactions 会更容易。然后,您需要在多维数据集之间建立连接,然后创建一个特殊维度,并将subQuery 属性设置为true。我在下面提供了一个示例以帮助您理解:

cube('Transactions', 
  sql: `SELECT * FROM postgres.transactions`,

  measures: 
    spend: 
      sql: `total_amount`,
      type: `number`,
    ,
  ,

  dimensions: 
    eventId: 
      sql: `event_id`,
      type: `string`
    ,

    customerId: 
      sql: `customer_id`,
      type: `string`
    ,

    transactionDate: 
      sql: `transaction_date`,
      type: `time`
    ,
  ,
)

cube('Customers', 
  sql: `SELECT customer_id FROM postgres.transactions`,

  joins: 
    Transactions: 
      relationship: `hasMany`,
      sql: `$Customers.id = $Transactions.customerId`
    
  ,

  measures: 
    averageSpend: 
      sql: `$spendAmount`,
      type: `avg`,
    ,
  ,

  dimensions: 
    id: 
      sql: `customer_id`,
      type: `string`
    ,
    spendAmount: 
      sql: `$Transactions.spend`,
      type: `number`,
      subQuery: true
    ,
  
)

您可以在Subquery page on the documentation找到更多信息

【讨论】:

以上是关于如何在 cube.js 中实现子查询的主要内容,如果未能解决你的问题,请参考以下文章

HTML中实现子容器垂直居中的几种方式

在 Greenplum 中实现公用表表达式

如何在子查询中实现多列过滤

cube.js 学习cube.js segments 说明

Cube.js 作为报告工具

mybatis分页查询,SqlServer 2008 查询速度很慢