【问题标题】:Can the categories in the postgres tablefunc crosstab() function be integers?postgres tablefunc crosstab() 函数中的类别可以是整数吗?
【发布时间】:2017-12-19 16:51:13
【问题描述】:

这一切都在标题中。文档有这样的内容:

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 表以使用文本标识符进行实验室测试?

谢谢大家的帮助。非常感谢。

编辑:在 Dmitry 的帮助下弄明白了。他已经弄清楚了数据布局,但我不清楚我需要什么样的输出。我试图让数据透视表基于 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】:

    如果我理解正确,您的表格如下所示:

    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_1, result_2)。在我的查询中,我将得到最多 3 个结果。如果我有超过 3 个结果,那么我将看不到它们,如果我有少于 3 个结果,我会得到空值。

    这个查询的结果是:

    test_name |result_1 |result_2 |result_3
    ---------------------------------------
    test1     |result1  |result2  |<null>
    test2     |result3  |result4  |result5
    

    【讨论】:

    • 谢谢德米特里。从您提供的内容中得到了我想要的输出。编辑了我的原始帖子以显示这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-07
    • 1970-01-01
    • 1970-01-01
    • 2012-12-10
    • 2012-10-25
    • 1970-01-01
    相关资源
    最近更新 更多