sql - 按另一个列值分组和计数

标签 sql postgresql aggregate greatest-n-per-group

我有如下表格:

CREATE TABLE public.test_table
(
    "ID" serial PRIMARY KEY NOT NULL,
    "CID" integer NOT NULL,
    "SEG" integer NOT NULL,
    "DDN" character varying(3) NOT NULL
)

数据看起来像这样:

ID  CID SEG DDN
1   1   1   "711"
2   1   2   "800"
3   1   3   "124"
4   2   1   "711"
5   3   1   "711"
6   3   2   "802"
7   4   1   "799"
8   5   1   "799"
9   5   2   "804"
10  6   1   "799"

我需要按 CID 列对这些数据进行分组,并根据 DDN 列的第一个值获取列计数,但计数必须给我两个不同的信息,无论是否大于 1。

如果不能解释清楚,真的很抱歉。让我告诉你我需要什么..

DDN END TRA
711 1   2
799 2   1

可以看到,DDN:711有1条单次计数记录(ID:4)。这是 END 列。 但是 2 次有多个 SEG 计数(ID:1to3 和 ID:5to6)。这是 TRA 专栏。

我不能确定什么列应该在组子句中!

我的解决方案:

刚刚找到如下解决方案

WITH x AS (
    SELECT
        (SELECT t1."DDN" FROM public.test_table AS t1
         WHERE t1."CID"=t."CID" AND t1."SEG"=1) AS ddn,
        COUNT("CID") AS seg_count       
    FROM public.test_table AS t
    GROUP BY "CID"
)

SELECT ddn, COUNT(seg_count) AS "TOTAL",    
    SUM(CASE WHEN x.seg_count=1 THEN 1 ELSE 0 END) as "END",
    SUM(CASE WHEN x.seg_count>1 THEN 1 ELSE 0 END) as "TRA"
FROM x
GROUP BY ddn;

最佳答案

等效的、更快的查询:

SELECT "DDN"
     , COUNT(*) AS "TOTAL"
     , COUNT(*) FILTER (WHERE seg_count = 1) AS "END"
     , COUNT(*) FILTER (WHERE seg_count > 1) AS "TRA"
FROM  (
   SELECT DISTINCT ON ("CID")
         "DDN"          -- assuming min "SEG" is always 1
       , COUNT(*) OVER (PARTITION BY "CID") AS seg_count
   FROM   test_table
   ORDER  BY "CID", "SEG"
   ) sub
GROUP  BY "DDN";

db<> fiddle here

注意事项

CTE 通常较慢,应仅在 Postgres 中需要的地方使用。

这等同于问题中的查询假设每个“CID”的最小“SEG”总是1 - 因为此查询返回具有最小值的行"SEG"而您的查询返回带有 "SEG"= 1 的那个。通常,您会想要“第一”段,而我的查询更可靠地实现了此要求,但这在问题中并不清楚。

COUNT(*)COUNT(column) 稍快,并且不涉及 NULL 值(适用于此处)。相关:

关于 DISTINCT ON:

聚合 FILTER 语法需要 Postgres 9.4+:

关于sql - 按另一个列值分组和计数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52275571/

相关文章:

sql - 带有关系表的 Postgres tsvector

ruby-on-rails - 捆绑执行 rake db :migrate -- schema. rb 重新生成,没有索引

sql - 创建 SQL 模式 (postgresql)

mongodb - 带有空id的graphql查询返回对象

SQL 分割函数

mysql - mysql中结果集的情况

sql - SQLite3,“ALTER TABLE”和持久性

ruby-on-rails - 使用 postgres 数组的 Rails OR 查询

mysql - 使用 Mysql JOIN 进行 DISTINCT SUM

sql - 在没有游标的情况下合并单个SQL表中的数据