公共表表达式(CTE)

CTE 与 视图 类似,它们帮助您简化查询的复杂性,将长而复杂的 SQL 语句分解,并提高可读性和可重用性。

您已经在 快速开始 文档中阅读了一个 CTE 的例子。

什么是公共表表达式 (CTE)?

公共表表达式 (CTE) 是可以在 SELECTINSERTUPDATEDELETE 语句中引用的临时结果集。CTE 有助于将复杂的查询分解成更可读的部分,并且可以在同一个查询中多次引用。

CTE 的基本语法

CTE 通常使用 WITH 关键字定义。基本语法如下:

  1. WITH cte_name [(column1, column2, ...)] AS (
  2. QUERY
  3. )
  4. SELECT ...
  5. FROM cte_name;

示例解释

接下来,我们将通过一个完整的示例来演示如何使用 CTE,包括数据准备、CTE 创建和使用。

步骤 1:创建示例数据

假设我们有以下两个表:

  • grpc_latencies:包含 gRPC 请求延迟数据。
  • app_logs:包含应用程序日志信息。
  1. CREATE TABLE grpc_latencies (
  2. ts TIMESTAMP TIME INDEX,
  3. host VARCHAR(255),
  4. latency FLOAT,
  5. PRIMARY KEY(host),
  6. );
  7. INSERT INTO grpc_latencies VALUES
  8. ('2023-10-01 10:00:00', 'host1', 120),
  9. ('2023-10-01 10:00:00', 'host2', 150),
  10. ('2023-10-01 10:00:05', 'host1', 130);
  11. CREATE TABLE app_logs (
  12. ts TIMESTAMP TIME INDEX,
  13. host VARCHAR(255),
  14. log TEXT,
  15. log_level VARCHAR(50),
  16. PRIMARY KEY(host, log_level),
  17. );
  18. INSERT INTO app_logs VALUES
  19. ('2023-10-01 10:00:00', 'host1', 'Error on service', 'ERROR'),
  20. ('2023-10-01 10:00:00', 'host2', 'All services OK', 'INFO'),
  21. ('2023-10-01 10:00:05', 'host1', 'Error connecting to DB', 'ERROR');

步骤 2:定义和使用 CTE

我们将创建两个 CTE 来分别计算第 95 百分位延迟和错误日志的数量。

  1. WITH
  2. metrics AS (
  3. SELECT
  4. ts,
  5. host,
  6. approx_percentile_cont(latency, 0.95) RANGE '5s' AS p95_latency
  7. FROM
  8. grpc_latencies
  9. ALIGN '5s' FILL PREV
  10. ),
  11. logs AS (
  12. SELECT
  13. ts,
  14. host,
  15. COUNT(log) RANGE '5s' AS num_errors
  16. FROM
  17. app_logs
  18. WHERE
  19. log_level = 'ERROR'
  20. ALIGN '5s' BY (HOST)
  21. )
  22. SELECT
  23. metrics.ts,
  24. metrics.host,
  25. metrics.p95_latency,
  26. COALESCE(logs.num_errors, 0) AS num_errors
  27. FROM
  28. metrics
  29. LEFT JOIN logs ON metrics.host = logs.host AND metrics.ts = logs.ts
  30. ORDER BY
  31. metrics.ts;

输出:

  1. +---------------------+-------+-------------+------------+
  2. | ts | host | p95_latency | num_errors |
  3. +---------------------+-------+-------------+------------+
  4. | 2023-10-01 10:00:00 | host2 | 150 | 0 |
  5. | 2023-10-01 10:00:00 | host1 | 120 | 1 |
  6. | 2023-10-01 10:00:05 | host1 | 130 | 1 |
  7. +---------------------+-------+-------------+------------+

详细说明

  1. 定义 CTEs
  • metrics:

    1. WITH
    2. metrics AS (
    3. SELECT
    4. ts,
    5. host,
    6. approx_percentile_cont(latency, 0.95) RANGE '5s' AS p95_latency
    7. FROM
    8. grpc_latencies
    9. ALIGN '5s' FILL PREV
    10. ),

    这里我们使用范围查询计算每个 host 在每个 5 秒时间窗口内的第 95 百分位延迟。

  • logs:

    1. logs AS (
    2. SELECT
    3. ts,
    4. host,
    5. COUNT(log) RANGE '5s' AS num_errors
    6. FROM
    7. app_logs
    8. WHERE
    9. log_level = 'ERROR'
    10. ALIGN '5s' BY (HOST)
    11. )

    同样地,我们计算每个 host 在每个 5 秒时间窗口内的错误日志数量。

  1. 使用 CTEs: 在最终的查询部分:

    1. SELECT
    2. metrics.ts,
    3. metrics.host,
    4. metrics.p95_latency,
    5. COALESCE(logs.num_errors, 0) AS num_errors
    6. FROM
    7. metrics
    8. LEFT JOIN logs ON metrics.host = logs.host AND metrics.ts = logs.ts
    9. ORDER BY
    10. metrics.ts;

    我们对两个 CTE 结果集进行左连接,以获得最终的综合分析结果。

总结

通过 CTE,您可以将复杂的 SQL 查询分解为更易于管理和理解的部分。在本示例中,我们分别创建了两个 CTE 来计算第 95 百分位延迟和错误日志的数量,然后将它们合并到最终查询中进行分析。 阅读更多 WITH