0

我有一个聚合一些 UNION ALL 选择的子查询。除此之外,我准备SELECT创建交叉表并将其限制为 20 个。我希望能够在将子查询结果限制在主查询中之前检索它们的总数。这是为了尝试构建一个分页来接收记录总数,然后是特定的页面记录网格。

示例查询:

SELECT 
    name, 
    sumIf(metric_value, metric_name = 'data') AS data,
    sumif(....
FROM
    (SELECT 
         name, metric_name, SUM(metric_value) as metric_value 
     FROM
         (SELECT 
              name, 'data' AS metric_name, SUM(data) AS metric_value 
          FROM 
              table 
          WHERE 
              date > '2017-01-01 00:00:00' 
          GROUP BY 
              name

          UNION ALL

          SELECT 
              name, 'data' AS metric_name, SUM(data) AS metric_value 
          FROM 
              table2 
          WHERE 
              date > '2017-01-01 00:00:00' 
          GROUP BY 
              name

          UNION ALL

          SELECT 
              name, 'data' AS metric_name, SUM(data) AS metric_value 
          FROM 
              table3 
          WHERE 
              date > '2017-01-01 00:00:00' 
          GROUP BY 
              name

          UNION ALL

          .
          .
          .)
    GROUP BY 
        name, metric_name)
GROUP BY 
    name 
ORDER BY 
    name ASC
LIMIT 0,20;

第一个子选择返回大量数据,所以我想我可以计算它并作为一个列值或行返回,它会传播到限制 20 个结果的主选择。因为我需要知道整个结果集,但不想无限制地调用同一个查询两次,而有限制地只是为了获得 COUNT。至少有 12 个 UNION ALL 三级子选择,何必浪费资源。我希望尝试与 ClickHouse 不一定相关的通用 SQL 解决方案

我正在考虑使用count(*) OVER (),但是不支持,所以如果那是唯一的选项,我知道我需要运行两次查询。

4

1 回答 1

0

应该提到的第一件事是,通常没有人对查询的确切页数感兴趣。它可以很容易地估算出来,几乎没有人会关心估算的准确性。但是,如果您有指向 GUI 中最后一页的链接,人们通常会单击链接以查看它是否有效。

然而,在某些情况下,分析师应该访问所有页面,然后 GUI 应该显示确切的工作量。一个好消息是,在后一种情况下,更好的策略是缓存整个结果表的快照,计算表中的行数不再是问题。

我的意思是,与客户讨论他们是否真的需要它是有意义的,因为每天多次不必要的全面扫描可能会影响数据库负载和计费总额。

无论如何,如果您仍然需要估计行数,您可以简化查询,只计算行数。据我了解,这类似于:

SELECT SUM(cnt) as row_count
FROM (
    SELECT COUNT(DISTINCT name) as cnt FROM table1 WHERE date > ...
    UNION ALL
    SELECT COUNT(DISTINCT name) as cnt FROM table2 WHERE date > ...
    ...
) as counts;

或者如果data是一个常量度量名称

SELECT COUNT(DISTINCT name) as row_count
FROM (
    SELECT DISTINCT name FROM table1 WHERE date > ...
    UNION ALL
    SELECT DISTINCT name FROM table2 WHERE date > ...
    ...
) as names;
于 2017-08-29T20:12:06.973 回答