小编典典

GROUP BY或COUNT之类的字段值-UNPIVOT?

sql

我有一个带有测试字段的表格,示例

id         | test1    | test2    | test3    | test4    | test5
+----------+----------+----------+----------+----------+----------+
12345      | P        | P        | F        | I        | P

因此,对于每条记录,我想知道有多少次通过,失败或不完整(P,F或I)

有没有一种方法可以按价值分组?

伪:

SELECT ('P' IN (fields)) AS pass
WHERE id = 12345

我有大约40个测试字段,我需要以某种方式将它们组合在一起,而我真的不想编写这个超级丑陋,冗长的查询。是的,我知道我应该将表重写为两个或三个单独的表,但这是另一个问题。

预期成绩:

passed     | failed   | incomplete
+----------+----------+----------+
3          | 1        | 1

有什么建议吗?

注意:我正在运行PostgreSQL 7.4,是的,我们正在升级


阅读 221

收藏
2021-04-17

共1个答案

小编典典

我可能想出了一个解决方案:

SELECT id
      ,l - length(replace(t, 'P', '')) AS nr_p
      ,l - length(replace(t, 'F', '')) AS nr_f
      ,l - length(replace(t, 'I', '')) AS nr_i
FROM   (SELECT id, test::text AS t, length(test::text) AS l  FROM test) t

技巧如下:

  • 将行类型转换为其文本表示形式。
  • 测量字符长度。
  • 替换要计算的字符并测量长度变化。
  • 计算子选择中原始行的长度,以供重复使用。

这就要求P, F, I该行中没有其他地方。使用子选择来排除可能干扰的任何其他列。

在8.4-9.1中测试。如今,没有人使用PostgreSQL
7.4,您必须进行自我测试。我仅使用基本功能,但不确定在7.4中将行类型强制转换为文本是否可行。如果这不起作用,则必须手工连接所有测试列一次:

SELECT id
      ,length(t) - length(replace(t, 'P', '')) AS nr_p
      ,length(t) - length(replace(t, 'F', '')) AS nr_f
      ,length(t) - length(replace(t, 'I', '')) AS nr_i
FROM   (SELECT id, test1||test2||test3||test4 AS t FROM test) t

这要求所有列都为NOT NULL

2021-04-17