我正在使用 Grafana Athena 插件来分析时间序列数据。我想允许我的用户在下拉列表中选择多个列并将它们显示在面板中。为此,我使用如下查询:
SELECT
$__timeGroup(t, $__interval) as time,
AVG(${signal:csv}) as ${signal:text}
FROM
my_table
WHERE
$__timeFilter(t)
GROUP BY
$__timeGroup(t, $__interval)
当下拉信号值仅等于 1 列时,这将按预期工作。但是,我希望用户能够返回超过 1 列并显示结果。我可以通过如下查询手动执行此操作:
SELECT
$__timeGroup(t, $__interval) as time,
AVG(col1) as avg_col1,
AVG(col2) as avg_col2
FROM
my_table
WHERE
$__timeFilter(t)
GROUP BY
$__timeGroup(t, $__interval)
但是,问题是我希望用户能够在 1 和 e.g. 之间进行选择。通过下拉菜单最多 10 列 - 然后相应地显示。
我有一个“非理想”解决方案,我创建一个变量,该变量返回所需文本中“包装”的列名称,即如下所示:
SELECT
CONCAT('AVG(', column_name, ') as avg_', column_name)
FROM
information_schema.columns
WHERE
table_schema = '${database:csv}'
AND table_name = 'tbl_${device:csv}_${message:csv}'
这可行,但暗示用户现在正在查看还包括包装文本的变量下拉列表 - 这并不理想。
为了解决这个问题,我尝试了以下方法:
SELECT
column_name as __text, CONCAT('AVG(', column_name, ') as avg_', column_name) AS __value
FROM
information_schema.columns
WHERE
table_schema = '${database:csv}'
AND table_name = 'tbl_${device:csv}_${message:csv}'
这会导致下拉列表看起来符合预期(仅显示
column_name
文本),但当我使用查询时,这些值也恰好等于列名称,如下所示:
SELECT
$__timeGroup(t, $__interval) as time,
${signal:csv}
FROM
tbl_${device}_${message:csv}
WHERE
$__timeFilter(t)
GROUP BY
$__timeGroup(t, $__interval)
这似乎与例如中的指导形成鲜明对比。 本文档指出人们应该能够使用以下内容:
SELECT hostname AS __text, id AS __value FROM my_host
知道我错过了什么吗?
此外,如果有某种替代方法可以简单地返回列名称并调整我的面板查询以达到预期结果,我愿意接受想法。
您需要将聚合和列选择分开:聚合所有列,然后仅返回需要的列。
这可以通过子查询或 CTE 来完成。这是例子:
WITH aggregated_data AS (
SELECT
$__timeGroup(t, $__interval) as time,
AVG(col1) as col1,
AVG(col2) as col2,
AVG(col3) as col3,
AVG(col4) as col4,
AVG(col5) as col5
FROM my_table
WHERE $__timeFilter(t)
GROUP BY $__timeGroup(t, $__interval)
)
SELECT time, ${signal:csv}
FROM aggregated_data
或者,如果您有“极其”大量的列,并且所有列的聚合是不可取/不可行的,并且为了保持一切整洁,您可以按原样保持变量,但创建一个附加(隐藏)变量,该变量将包含包裹表达式。 为此,您需要:
添加类型为
select
array_join(
transform(
split('${signal:csv}', ','),
x -> 'AVG(' || x || ') as AVG_' || x),
', ');
这样,您的初始列列表(例如“col1,col2,col3”)将转换为“AVG(col1) as AVG_col1, AVG(col2) as AVG_col2, AVG(col3) as AVG_col3”,并且可以在以后使用以通常的方式在面板查询中
SELECT
$__timeGroup(t, $__interval) as time,
$my_prepared_columns
FROM my_table
WHERE $__timeFilter(t)
GROUP BY $__timeGroup(t, $__interval)