postgresql row convert column

438

Install the additional module tablefunc once per database, which provides the function crosstab(). Since Postgres 9.1 you can use CREATE EXTENSION for that:

CREATE EXTENSION IF NOTEXISTS tablefunc;

Improved test case

CREATETABLE tbl (
   section   text
 , status    text
 , ct        integer-- "count" is a reserved word in standard SQL
);

INSERTINTO tbl VALUES 
  ('A', 'Active', 1), ('A', 'Inactive', 2)
, ('B', 'Active', 4), ('B', 'Inactive', 5)
                    , ('C', 'Inactive', 7);  -- ('C', 'Active') is missing

Simple form - not fit for missing attributes

crosstab(text) with 1 input parameter:

SELECT*FROM   crosstab(
   'SELECT section, status, ct
    FROM   tbl
    ORDER  BY 1,2'-- needs to be "ORDER BY 1,2" here
   ) AS ct ("Section" text, "Active" int, "Inactive" int);

Returns:

Section | Active | Inactive

---------+--------+----------

A | 1 | 2

B | 4 | 5

C | 7 | -- !!

  • No need for casting and renaming.

  • Note the incorrect result for C: the value 7 is filled in for the first column. Sometimes, this behavior is desirable, but not for this use case.

  • The simple form is also limited to exactly three columns in the provided input query: row_name, category, value. There is no room for extra columns like in the 2-parameter alternative below.

Safe form

crosstab(text, text) with 2 input parameters:

SELECT*FROM   crosstab(
   'SELECT section, status, ct
    FROM   tbl
    ORDER  BY 1,2'-- could also just be "ORDER BY 1" here

  , $$VALUES ('Active'::text), ('Inactive')$$
   ) AS ct ("Section" text, "Active" int, "Inactive" int);

Returns:

Section | Active | Inactive

---------+--------+----------

A | 1 | 2

B | 4 | 5

C | | 7 -- !!

  • Note the correct result for C.

  • The second parameter can be any query that returns one row per attribute matching the order of the column definition at the end. Often you will want to query distinct attributes from the underlying table like this:

'SELECT DISTINCT attribute FROM tbl ORDER BY 1'

That's in the manual.

Since you have to spell out all columns in a column definition list anyway (except for pre-defined crosstabN() variants), it is typically more efficient to provide a short list in a VALUES expression like demonstrated:

    $$VALUES ('Active'::text), ('Inactive')$$)

Or (not in the manual):

    $$SELECTunnest('{Active,Inactive}'::text[])$$  -- short syntax for long lists
  • You can even output columns with different data types with crosstab(text, text) - as long as the text representation of the value column is valid input for the target type. This way you might have attributes of different kind and output text, date, numeric etc. for respective attributes. There is a code example at the end of the chapter crosstab(text, text) in the manual.

db<>fiddle here

Effect of excess input rows

Excess input rows are handled differently - duplicate rows for the same ("row_name", "category") combination - (section, status) in the above example.

The 1-parameter form fills in available value columns from left to right. Excess values are discarded.

Earlier input rows win.

The 2-parameter form assigns each input value to its dedicated column, overwriting any previous assignment.

Later input rows win.

Typically, you don't have duplicates to begin with. But if you do, carefully adjust the sort order to your requirements - and document what's happening.

Or get fast arbitrary results if you don't care. Just be aware of the effect.

Advanced examples

\crosstabview in psql

Postgres 9.6 added this meta-command to its default interactive terminal psql. You can run the query you would use as first crosstab() parameter and feed it to \crosstabview (immediately or in the next step). Like:

db=>SELECT section, status, ct FROM tbl \crosstabview

Similar result as above, but it's a representation feature on the client side exclusively. Input rows are treated slightly differently, hence ORDER BY is not required. Details for \crosstabview in the manual. There are more code examples at the bottom of that page.

Related answer on dba.SE by Daniel Vérité (the author of the psql feature):

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: postgresql convert函数可以将一个数据类型转换为另一个数据类型。它的语法如下: CONVERT(type, expression) 其中,type是要转换的数据类型,expression是要转换的表达式。例如,将一个字符串转换为整数: SELECT CONVERT(integer, '123'); ### 回答2: PostgreSQL是一种结构化查询语言(SQL)数据库管理系统,它支持很多内置的函数,例如,CONVERT函数。 CONVERT函数是PostgreSQL提供的一个字符串转换函数,主要用于将字符串从一种数据类型转换成另一种数据类型。该函数的语法如下: ``` CONVERT(source_string, destination_data_type) ``` 其中,source_string代表要转换的源字符串,destination_data_type代表转换后的目标数据类型。 CONVERT函数支持的目标数据类型包括: - BOOL(布尔型) - INTEGER(整型) - FLOAT(浮点型) - DATE(日期型) - TIME(时间型) - TIMESTAMP(时间戳型) 例如,我们可以将字符串'123'转换成整型,如下所示: ``` SELECT CONVERT('123', INTEGER); ``` 该语句的输出结果为123(整型)。 需要注意的是,如果源字符串无法转换成目标数据类型,那么CONVERT函数会抛出一个错误。此外,如果需要将字符串转换成其他数据类型(例如,十六进制),则需要使用其他函数(例如,CAST函数)。 在实际的开发中,CONVERT函数常用于数据类型转换、字符串拼接、数据格式化等场景,非常方便实用。 ### 回答3: PostgreSQL是一种功能非常强大的开源关系型数据库系统,可以满足各种不同的应用场景。其中,Convert函数是一个非常有用的函数,可以用于将不同的数据类型之间进行转换。 Convert函数可以通过指定转换的源数据类型和目标数据类型来实现数据类型的转换。通常情况下,Convert函数用于将字符串类型转换为数字类型,或者将数字类型转换为字符串类型。 在使用Convert函数时,需要注意数据类型的精度和转换后数据的格式。如果不小心将一个字符转换为数字类型时精度不够,可能会导致数据失真。同样,如果没有指定好字符串转换为数字类型时的格式,也可能会造成错误的结果。 另外,因为PostgreSQL支持多种不同的数据类型,所以转换过程中可能会出现一些不兼容的情况。在这种情况下,需要通过使用其他函数或者进行多次转换来实现最终的数据类型转换。 总之,Convert函数是PostgreSQL中非常基础和常用的一个函数,在数据处理中使用频率非常高。熟练掌握Convert函数的使用方法,可以更加方便地实现不同类型之间的数据转换,提高数据处理的效率和准确性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值