【问题标题】:Postgresql - Group ByPostgresql - 分组依据
【发布时间】:2021-02-11 15:06:11
【问题描述】:

我有一个简单的 groupby 场景。以下是查询的输出。

查询是: select target_date, type, count(*) from table_name group by target_date, type

查询和输出非常好。 我的问题是我在 Grafana 中使用它进行绘图。那就是以 postgres 作为后端的 Grafana。 发生的情况是,由于在 2020 年 1 月 10 日和 2020 年 3 月 10 日错过了“type2”类别,因此根本不会绘制 type2 类别(并排条形图)。虽然“type2”在其他日子里也有。

它期待一些类似的东西

因此,每当日期中缺少一个类别时,我们需要一个 0 值的计数。 需要在查询中处理这个,因为源数据不能被修改。 感谢您提供任何帮助。

【问题讨论】:

  • WHERE t3.weekday = 'N' 将您的外连接变为内连接,因为在外连接行中,t3.weekday 为空。将此更改为AND t3.weekday = 'N',使其成为ON 子句的一部分。

标签: sql postgresql group-by grafana


【解决方案1】:

您需要创建一个包含所有target_date/type 组合的列表。这可以通过CROSS JOIN 中的两个DISTINCT 选择target_datetype 来完成。此列表可以LEFT JOINed 到table_name 以获取每个组合的计数:

SELECT dates.target_date, types.type, COUNT(t.target_date)
FROM (
  SELECT DISTINCT target_date
  FROM table_name
) dates
CROSS JOIN (
  SELECT DISTINCT type
  FROM table_name
) types
LEFT JOIN table_name t ON t.target_date = dates.target_date AND t.type = types.type
GROUP BY dates.target_date, types.type
ORDER BY dates.target_date, types.type

Demo on dbfiddle

【讨论】:

  • 这真的很有帮助。假设我想在我的左连接表上添加条件检查,即 table_name where weekday="N" [select target_date, type, count(*) from table_name group by target_date, type where weekday="N" ] 我尝试添加它,加入后但结果是错误的。这里有什么帮助吗?
  • 你需要t.weekday = 'N' 注意你需要一个表别名并且你应该使用单引号,而不是双引号 n
  • 是的,我做到了。用我用于此的查询更新了问题。但结果却像以前一样丢失了类别。
  • @Learner 您需要将条件t.weekday = 'N' 添加到Nick 查询中最后一个左连接的ON 子句中。这里的问题是,如果您将weekday 的限制放入WHERE 子句中,您可能会删除一些您想要保留的记录。
  • @Learner 正如 Tim 所说,只需将 LEFT JOIN table_name t ON t.target_date = dates.target_date AND t.type = types.type 更改为 LEFT JOIN table_name t ON t.target_date = dates.target_date AND t.type = types.type AND t.weekday = 'N' 即可获得所需的结果。
【解决方案2】:

您可以在这里使用日历表方法:

SELECT
    t1.target_date,
    t2.type,
    COUNT(t3.target_date) AS count
FROM (SELECT DISTINCT target_date FROM yourTable) t1
CROSS JOIN (SELECT DISTINCT type FROM yourTable) t2
LEFT JOIN yourTable t3
    ON t3.target_date = t1.target_date AND
       t3.type = t2.type
GROUP BY
    t1.target_date,
    t2.type
ORDER BY
    t1.target_date,
    t2.type;

这里的想法是交叉连接子查询以查找所有不同的目标日期和类型,以生成查询的起点。然后,我们将此中间表连接到您的实际表,并找到每个日期和类型的计数。

【讨论】:

  • 通过添加条件修改问题。给出了我使用的查询和相应的输出。你能帮忙看看如何在左连接或主表中添加额外的条件吗?
  • ...我已经回滚了你的问题。只需将 WHERE 条件移动到最后一个联接的 ON 子句即可。请不要在很多人已经回答后更改您的问题。这不是 Stack Overflow 格式的工作原理。
【解决方案3】:
select t.target_date, tmp.type, sum(case when t.type = tmp.type then 1 else 0 end) 
from your_table t
cross join (select distinct type from your_table) tmp
group by t.target_date, tmp.type

Demo

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-07
    • 2021-10-29
    • 1970-01-01
    • 2015-06-14
    • 2019-11-17
    • 2023-02-25
    相关资源
    最近更新 更多