我根据 PostgresQL 数据库返回的结果集构建了一个 Excel 文档。 我需要能够区分结果集返回的十进制(双精度)和非十进制(整数)数字。
我的 SQL 如下所示:
...
(select product, reportflag,
(select measure_name from report_measures rm where rm.measure_key = typeflag and rm.object_id=(select object_id from reportdet)) as salesLoss,
(case when skunumber = 'MULTIPLE' then '-1' else skunumber end)::varchar(12) as skunumber, skuname, null::varchar(12) as substitutesku,
null as substituteskuname,
null::decimal as substituteTransferSales,
case when measure_symbol[3] = '%' then ((measures ->> measure_key[3])::decimal)/100 else (measures ->> measure_key[3])::decimal end as totalSpend,
case when measure_symbol[4] = '%' then ((measures ->> measure_key[4])::decimal)/100 else (measures ->> measure_key[4])::bigint end as totalUnits, <-- this neeeds to be an integer
case when measure_symbol[5] = '%' then ((measures ->> measure_key[5])::decimal)/100 else (measures ->> measure_key[5])::decimal end as totalVisits,
...
我需要
totalUnits
字段是某种整数。但是,它返回为 decimal
。
我使用以下内容来检测字段的类型:
public void processRow(ResultSet rs) throws SQLException {
var rsmd = rs.getMetaData();
...
}
然后,当我检查
rcmd
时,我可以看到以下类型:
rsmd = {PgResultSetMetaData@21873}
connection = {PgConnection@21880}
fields = {Field[55]@21881}
0 = {Field@21882} "Field(product,TEXT,65535,T)"
1 = {Field@21883} "Field(reportflag,TEXT,65535,T)"
2 = {Field@21884} "Field(salesloss,VARCHAR,65535,T)"
3 = {Field@21885} "Field(skunumber,VARCHAR,65535,T)"
4 = {Field@21886} "Field(skuname,TEXT,65535,T)"
5 = {Field@21887} "Field(substitutesku,VARCHAR,65535,T)"
6 = {Field@21888} "Field(substituteskuname,TEXT,65535,T)"
7 = {Field@21889} "Field(substitutetransfersales,NUMERIC,65535,T)"
8 = {Field@21890} "Field(totalspend,NUMERIC,65535,T)"
9 = {Field@21891} "Field(totalunits,NUMERIC,65535,T)" <-- this should be an integer
10 = {Field@21892} "Field(totalvisits,NUMERIC,65535,T)"
...
正如我们所见,
totalunits
返回为NUMERIC
,这是一种十进制类型,尽管我将其转换为bigint
。
我尝试在 SQL 中将该字段显式转换为
bigint
,如下所示:
case when measure_symbol[4] = '%' then ((measures ->> measure_key[4])::decimal)/100
else CAST(measures ->> measure_key[4] AS bigint) end as totalUnits,
,与上面的结果完全相同。
同时,上面提交的
skunumber
被正确转换为varchar。
我做错了什么?
我想这个问题在
CASE
声明中。
该语句可能返回不同的数据类型(decimal & bigint
,并且decimal
是两者的公共类型),因此不存在类型一致性。
根据您的查询:
case when measure_symbol[4] = '%'
then ((measures ->> measure_key[4])::decimal)/100 <-- it returns DECIMAL
else (measures ->> measure_key[4])::bigint end as totalUnits, <-- this neeeds to be an INTEGER
作为解决方案,您可以投射整个
CASE
-语句:
CAST(
case
when measure_symbol[4] = '%' then ((measures ->> measure_key[4])::decimal)/100
else measures ->> measure_key[4]::bigint
end
AS bigint) as totalUnits,
正如 @Albina 正确指出的那样,
case
语句的两边都应该返回相同的类型。
在挖掘时,我遇到了这个错误:“CASE 类型字符变化和数字无法匹配”,这导致我得到以下答案: 错误:CASE类型字符变化和数字无法匹配
此外,我必须四舍五入为 0,因为结果带有尾随
.0
。所以我最终得到的答案是:
ROUND(case when measure_symbol[4] = '%' then ((measures ->> measure_key[4])::decimal)/100 else (measures ->> measure_key[4])::decimal end, 0)::bigint as totalUnits,