【问题标题】:How can I create columns in postgres if I do not know how many it is?如果我不知道它有多少,如何在 postgres 中创建列?
【发布时间】:2021-04-19 18:08:44
【问题描述】:

我的问题是:我有一个返回此表的查询:

Result of my query

解释表格:它显示了一些问题及其数字答案(数字 0 可以表示否,数字 1 可以表示是,数字 2 可以表示一点等等)我想要的是这张表变成这样:

What I want

所以它告诉我每个答案选项中有多少个答案。但是,响应选项的数量会有所不同。在此示例中,我有 0 到 4 的选项,但在某些情况下选项从 0 到 10。那么,如何为每个选项创建列?

我的查询是这样的:

SELECT 
    data,
    id,
    question,
    answer,
    COUNT(*) AS info2,
    COUNT(CASE WHEN answer IS NOT NULL THEN 1 END) AS info3,
    COUNT(CASE WHEN answer IS NULL THEN 1 END) AS info4
FROM table1
JOIN table2
    ON table1.id = table2.id
WHERE table1.variable_y BETWEEN '2020-01-01 00:00:00' AND '2020-05-31 23:59:59'
    AND variable_x = 'ABC123'
    AND variable_z = 'ABC'
GROUP BY 1,2,3,4

【问题讨论】:

  • 欢迎来到 SO 社区。请花几分钟时间拨打Tour 并查看How to Ask。具体来说,将完整的表格定义 (ddl) 和示例日期显示为文本 -无图像(或提供 fiddle 和该数据的预期结果 - 也作为文本。我确实注意到你想要结果显示 "... res0, res1... info2, info3..." 但查询只返回 "...info2, info3..."。'res...' 列及其来源是什么?跨度>
  • 简单地说:你不能。 SQL 的基本限制之一是必须知道查询的所有列在查询实际执行之前。所以在解析语句时必须对每列的编号、名称和数据类型进行评估。您将必须编写尽可能多的表达式,因为您可以拥有列。例如写 50 篇作好准备。这种格式(将行转换为列)在前端做得更好。 SQL 根本不是为此而设计的。
  • 嗨@Luuk。我的问题出在 postgresql 中,所以对我没有帮助。
  • @HelenaMaia:我认为 postgresql 也支持动态 sql 吗?请参阅:12

标签: sql postgresql pivot


【解决方案1】:

您可以执行动态查询。最好的选择是使用编程语言,但也可以使用 sql 语言。

我做了一个简化的例子:

示例数据:

CREATE TABLE t (
answer int
);

INSERT INTO t VALUES (0);
INSERT INTO t VALUES (1);
INSERT INTO t VALUES (2);
INSERT INTO t VALUES (3);
INSERT INTO t VALUES (4);
INSERT INTO t VALUES (3);
INSERT INTO t VALUES (2);
INSERT INTO t VALUES (2);

动态查询:

(SELECT 'SELECT ')

UNION ALL

(SELECT 
    'SUM(CASE WHEN answer = ' || answer || ' THEN 1 ELSE 0 END) AS res' || answer || ','
FROM t
GROUP BY answer
ORDER BY answer)

UNION ALL

(SELECT 'COUNT(*) AS info2,
    SUM(CASE WHEN answer IS NOT NULL THEN 1 ELSE 0 END) AS info3,
    SUM(CASE WHEN answer IS NULL THEN 1 ELSE 0 END) AS info4 
    FROM t;')

输出是你想要的查询:

SELECT 
  SUM(CASE WHEN answer = 0 THEN 1 ELSE 0 END) AS res0,
  SUM(CASE WHEN answer = 1 THEN 1 ELSE 0 END) AS res1,
  SUM(CASE WHEN answer = 2 THEN 1 ELSE 0 END) AS res2,
  SUM(CASE WHEN answer = 3 THEN 1 ELSE 0 END) AS res3,
  SUM(CASE WHEN answer = 4 THEN 1 ELSE 0 END) AS res4,
  COUNT(*) AS info2,
  SUM(CASE WHEN answer IS NOT NULL THEN 1 ELSE 0 END) AS info3,
  SUM(CASE WHEN answer IS NULL THEN 1 ELSE 0 END) AS info4 
FROM t;

查询结果(执行您的愿望查询的结果):

res0 res1 res2 res3 res4 info2 info3 info4
1 1 3 2 1 8 8 0

【讨论】:

  • 您好!谢谢你的建议。但我不明白动态查询。我应该不加修改地应用动态查询吗?我不理解''之间的这些陈述 -> 示例:'SUM(CASE WHEN answer =' || answer || ' THEN 1 ELSE 0 END) AS res' ||回答 || ','
  • 你能解释更多吗? :)
  • 嗨@HelenaMaia,不客气!动态查询意味着您可以使用算法编写查询,在这种情况下,我使用 sql 查询来创建另一个查询(将返回期望结果的查询),使用编程语言更容易做到这一点。第一个查询创建第二个查询,如果您执行第二个查询,您将获得期望的输出。我做了一个小例子来向你展示这个想法。尝试执行我的示例来理解它。
猜你喜欢
  • 2021-08-05
  • 1970-01-01
  • 2010-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-29
  • 2012-06-25
  • 1970-01-01
相关资源
最近更新 更多