postgres tablefunc中的类别crosstab()函数可以是整数吗?

问题描述 投票:1回答:1

这一切都在标题中。文档有这样的东西:

SELECT * 
FROM crosstab('...') AS ct(row_name text, category_1 text, category_2 text);

我有两张桌子,lab_testslab_tests_results。所有lab_tests_results行都绑定到lab_tests表中的主键id整数。我正在尝试制作一个数据透视表,其中实验室测试(由整数标识)是行标题,相应的结果在表中。我无法解决整数或整数周围的语法错误。

目前的设置是否可以实现?我在文档中遗漏了什么吗?或者我是否需要执行各种内部联接来制作类别字符串?或者修改lab_tests_results表以使用文本标识符进行实验室测试?

谢谢你们的帮助。非常感激。

编辑:在德米特里的帮助下弄清楚了。他已经找到了数据布局,但我不清楚我需要什么样的输出。我试图让数据透视表基于lab_tests_results表中的batch_id数字。不得不敲定基本查询和转换数据类型。

SELECT *
 FROM crosstab('SELECT lab_tests_results.batch_id, lab_tests.test_name, lab_tests_results.test_result::FLOAT
                FROM lab_tests_results, lab_tests
                WHERE lab_tests.id=lab_tests_results.lab_test AND (lab_tests.test_name LIKE ''Test Name 1'' OR lab_tests.test_name LIKE ''Test Name 2'')
                ORDER BY 1,2'
            )   AS final_result(batch_id VARCHAR, test_name_1 FLOAT, test_name_2 FLOAT);

这提供了lab_tests_results表中的数据透视表,如下所示:

batch_id   |test_name_1 |test_name_2 
---------------------------------------
batch1     |  result1   |   <null>
batch2     |  result2   |  result3  
postgresql pivot-table crosstab
1个回答
1
投票

如果我理解正确,你的表看起来像这样:

CREATE TABLE lab_tests (
  id INTEGER PRIMARY KEY,
  name VARCHAR(500)
);

CREATE TABLE lab_tests_results (
  id INTEGER PRIMARY KEY,
  lab_tests_id INTEGER REFERENCES lab_tests (id),
  result TEXT
);

您的数据看起来像这样:

INSERT INTO lab_tests (id, name) 
VALUES (1, 'test1'),
       (2, 'test2');

INSERT INTO lab_tests_results (id, lab_tests_id, result)
VALUES (1,1,'result1'),
       (2,1,'result2'),
       (3,2,'result3'),
       (4,2,'result4'),
       (5,2,'result5');

首先crosstabtablefunc的一部分,你需要启用它:

CREATE EXTENSION tablefunc;

根据this的答案,你需要为每个数据库运行一个。

最终查询将如下所示:

SELECT *
FROM crosstab(
    'SELECT lt.name::TEXT, lt.id, ltr.result
     FROM lab_tests AS lt
     JOIN lab_tests_results ltr ON ltr.lab_tests_id = lt.id'
) AS ct(test_name text, result_1 text, result_2 text, result_3 text);

说明: crosstab()函数接受一个查询文本,该文本应返回3列; (1)用于组名称的列,(2)用于分组的列,(3)该值。包装查询只选择crosstab()返回的所有值,并定义后面的列表(AS之后的部分)。首先是类别名称(test_name),然后是值(result_1result_2)。在我的查询中,我将获得最多3个结果。如果我有超过3个结果,那么我将不会看到它们,如果我有少于3个结果,我将得到空值。

此查询的结果是:

test_name |result_1 |result_2 |result_3
---------------------------------------
test1     |result1  |result2  |<null>
test2     |result3  |result4  |result5
© www.soinside.com 2019 - 2024. All rights reserved.