double precision从( float8) 到numeric四舍五入到 15 个有效小数位的转换,从而丢失信息。显然,更高的精度是可能的。转换为bigint(对于其范围内的值)可以保留更高的精度:
SELECT f8 AS float8
, f8::bigint AS to_bigint
, f8::numeric AS to_numeric
FROM (
VALUES
('8217316934885843456'::float8)
, ('8217316934885843457')
, ('8217316934885844479')
, ('8217316934885844480')
, ('8217316934885845503')
, ('8217316934885845584')
) t(f8);
float8 | to_bigint | to_numeric
-----------------------+---------------------+---------------------
8.217316934885843e+18 | 8217316934885842944 | 8217316934885840000
8.217316934885844e+18 | 8217316934885843968 | 8217316934885840000
8.217316934885844e+18 | 8217316934885843968 | 8217316934885840000
8.217316934885845e+18 | 8217316934885844992 | 8217316934885840000
8.217316934885845e+18 | 8217316934885844992 | 8217316934885840000
8.217316934885846e+18 | 8217316934885846016 | 8217316934885850000
(6 rows)
Run Code Online (Sandbox Code Playgroud)
db<>在这里摆弄 …
我有一个 Postgres 8.4 表,其中包含类型为“字符变化”的列,但我想将它们转换为枚举类型。
尝试更改表格时
ALTER TABLE logs ALTER COLUMN interface_type TYPE interface_types
USING interface_type::text::interface_types;
Run Code Online (Sandbox Code Playgroud)
我收到一个错误
default for column "interface_type" cannot be cast to type interface_types
Run Code Online (Sandbox Code Playgroud)
该列的默认值是枚举类型中值的文本版本。所以这应该是可能的,尽管我没有运气谷歌搜索解决方案。
我假设我需要为它定义一个演员表。如何?
我一生都无法弄清楚如何在我的 json 列的整数属性上创建索引。
我以这种方式尝试过(以及其他数十种方式)
CREATE INDEX user_reputation_idx ON users(("user"->>'reputation')::int)
Run Code Online (Sandbox Code Playgroud)
它在查询中工作得很好(例如ORDER BY ("user"->>'reputation')::int)
我错过了什么?
更新
我收到一个简单的语法错误,但是,我真的不知道为什么。
ERROR: syntax error at or near "::"
LINE 1: ... user_reputation_idx ON users (("user"->>'reputation')::int)
Run Code Online (Sandbox Code Playgroud)
表定义非常简单。它只是一列usertype json。
所以,看起来像这样:
CREATE TABLE users
(
"user" json
)
Run Code Online (Sandbox Code Playgroud) 当我查看一些查询的实际执行计划时,我注意到 WHERE 子句中使用的文字常量显示为计算标量和常量 scan的嵌套链。
为了重现这一点,我使用下表
CREATE TABLE Table1 (
[col1] [bigint] NOT NULL,
[col2] [varchar](50) NULL,
[col3] [char](200) NULL
)
CREATE NONCLUSTERED INDEX IX_Table1 ON Table1 (col1 ASC)
Run Code Online (Sandbox Code Playgroud)
里面有一些数据:
INSERT INTO Table1(col1) VALUES (1),(2),(3),
(-9223372036854775808),
(9223372036854775807),
(2147483647),(-2147483648)
Run Code Online (Sandbox Code Playgroud)
当我运行以下(废话)查询时:
SELECT a.col1, a.col2
FROM Table1 a, Table1 b
WHERE b.col1 > 2147483648
Run Code Online (Sandbox Code Playgroud)
我看到它将在索引查找和标量计算(来自常量)的结果中执行嵌套循环绘图。
请注意,文字大于 maxint。它确实有助于编写CAST(2147483648 as BIGINT). 知道为什么 MSSQL 将其推迟到执行计划中,并且有没有比使用强制转换更短的方法来避免它?它是否也会影响到准备好的语句(来自 jtds JDBC)的绑定参数?
标量计算并不总是完成(似乎是索引查找特定的)。有时查询分析器不会以图形方式显示它,而是col1 < scalar(expr1000)在谓词属性中显示它。
我已经在 Windows 7 上的 MS SSMS 2016 …
在将应用程序移植到 PostgreSQL (9.1) 时,我发现一个奇怪的 SQL 不兼容性与round()函数有关,特别是采用指示舍入精度的第二个参数的版本。
在 MySQL 中, round(some_float_column, 2)按预期工作,将some_float_column四舍五入的值返回到小数点后两位。在 Postgres 中,它错误ERROR: function round(double precision, integer) does not exist并建议HINT: No function matches the given name and argument types. You might need to add explicit type casts..
如文档所示...
http://www.postgresql.org/docs/9.1/static/functions-math.html
...Postgres 有两个轮函数,round(value)它采用双精度或数字,并round(value, precision)采用数字仅和一个整数。
所以,我不明白为什么 round 的两个参数形式不以 double 开头,但无论如何。在搜索中,我发现了这个问题的两种解决方案。一种是简单地创建我自己的版本round(value, precision),采用 (double, int) 并使用显式转换包装现有的 (numeric, int) 版本。这当然有效,但我不喜欢它(我的背景是 Oracle,它甚至没有真正的浮点类型)。在我看来,float/double 应该隐式转换为数字。事实证明,这些类型的 ASSIGNMENT 类型转换是预先定义的。但是 ASSIGNMENT 不适用于函数调用,正如我们在这里看到的,它需要是 IMPLICIT。与麻烦 …
我正在将现有应用程序迁移到 Amazon RDS PostgreSQL。该应用程序具有跨数据库支持,出于兼容性原因,它包含以下 SQL:
CREATE CAST (varchar AS numeric) WITH INOUT AS ASSIGNMENT
Run Code Online (Sandbox Code Playgroud)
在普通 PostgreSQL 上,这需要超级用户。在 Amazon RDS PostgreSQL 上这失败了
错误:必须是类型字符变化或数字类型的所有者
注意:我猜这是否是赋值或隐式转换无关紧要,但为了完整性而包含此信息。
考虑以下两种将日期时间 varchar 字符串转换为日期字段的方法:
SELECT convert(date, '2012-12-21 21:12:00', 20) -- Only date is needed
SELECT cast('2012-12-21 21:12:00' as date) -- Only date is needed
Run Code Online (Sandbox Code Playgroud)
两者都返回我期望的内容:不包括时间的日期,作为日期数据类型。
我的问题是:这两种方式有什么利弊吗?
当我使用099指示 0 填充的 3 位数字时,我会在左侧得到空格。
SELECT '>' || to_char(1, '099') || '<';
?column?
----------
> 001<
(1 row)
Run Code Online (Sandbox Code Playgroud)
为什么to_char这里是左填充?为什么会有前导空格?
为什么在下面的查询中 ResultFloat = 0?
我是否在cast/convert、sql_variant文档中遗漏了一点?
declare
@v sql_variant = convert(decimal(28,8), 20.0);
select sql_variant_property(@v, 'BaseType') as BaseType, -- 'decimal',
iif(convert(int, 10.0) < @v, 1, 0) as ResultInt, -- 1
iif(convert(decimal, 10.0) < @v, 1, 0) as ResultDecimal, -- 1
iif(convert(float, 10.0) < @v, 1, 0) as ResultFloat, -- 0 !
iif(convert(float, 10.0) < convert(float, @v), 1, 0) as ResultFloatFloat, -- 1
iif(convert(float, 10.0) < convert(decimal(28,8), @v), 1, 0) as ResultFloatDecimal; -- 1
Run Code Online (Sandbox Code Playgroud)
数据库服务器 2012
我创建了一个自定义类型:
CREATE TYPE my_type as(name text, street text, location text);
Run Code Online (Sandbox Code Playgroud)
初始化这样的类型很容易:
SELECT ROW('a', 'b', 'c')::my_type;
Run Code Online (Sandbox Code Playgroud)
我想知道是否有一种简单的方法可以部分初始化类型,这意味着所有未提及的列都隐式设置为 null。在伪代码中,类似于:
SELECT ROW('a', 'c')::my_type(name, location);
Run Code Online (Sandbox Code Playgroud)
另外,当列未按正确顺序提及时,是否还有一种初始化类型的方法?在伪代码中,类似于:
SELECT ROW('c', 'a', 'b')::my_type(location, name, street);
Run Code Online (Sandbox Code Playgroud) cast ×10
postgresql ×7
sql-server ×3
datatypes ×2
amazon-rds ×1
index ×1
json ×1
syntax ×1
t-sql ×1