# 类型转换函数
# toInt
将输入值转换为 Int 数据类型的值。该函数族包括:
toInt8(expr)
— 转换为 Int8 数据类型的值。toInt16(expr)
— 转换为 Int16 数据类型的值。toInt32(expr)
— 转换为 Int32 数据类型的值。toInt64(expr)
— 转换为 Int64 数据类型的值。toInt128(expr)
— 转换为 Int128 数据类型的值。toInt256(expr)
— 转换为 Int256 数据类型的值。
参数
expr
— 返回数字或以十进制表示的数字的字符串的表达式。不支持二进制、八进制和十六进制表示的数字。前导零将被删除。
返回值
Int8
、Int16
、Int32
、Int64
、Int128
或Int256
数据类型的整数值。- 函数使用向零舍入的方式,即截断数字的小数位。
- 函数对于 NaN 和 Inf 参数的行为是未定义的。在使用这些函数时,请注意数值转换问题。
示例
SELECT toInt32(32), toInt16('16'), toInt8(8.8);
┌─toInt32(32)─┬─toInt16('16')─┬─toInt8(8.8)─┐
│ 32 │ 16 │ 8 │
└─────────────┴───────────────┴─────────────┘
# toUInt
将输入值转换为 UInt 数据类型的值。该函数族包括:
toUInt8(expr)
— 转换为 UInt8 数据类型的值。toUInt16(expr)
— 转换为 UInt16 数据类型的值。toUInt32(expr)
— 转换为 UInt32 数据类型的值。toUInt64(expr)
— 转换为 UInt64 数据类型的值。toUInt256(expr)
— 转换为 UInt256 数据类型的值。
参数
expr
— 返回数字或以十进制表示的数字的字符串的表达式。不支持二进制、八进制和十六进制表示的数字。前导零将被删除。
返回值
UInt8
、UInt16
、UInt32
、UInt64
或UInt256
数据类型的整数值。- 函数使用向零舍入的方式,即截断数字的小数位。
- 函数对于负数参数、NaN 和 Inf 参数的行为是未定义的。例如,如果传递一个包含负数的字符串,例如
'-32'
,ClickHouse 将引发异常。在使用这些函数时,请注意数值转换问题。
示例
SELECT toUInt32(32), toUInt16('16'), toUInt8(8.8);
┌─toUInt32(32)─┬─toUInt16('16')─┬─toUInt8(8.8)─┐
│ 32 │ 16 │ 8 │
└──────────────┴────────────────┴──────────────┘
# toFloat
将输入值转换为 Float 数据类型的值。该函数族包括:
toFloat32(expr)
— 转换为 Float32 数据类型的值。toFloat64(expr)
— 转换为 Float64 数据类型的值。
参数
expr
— 返回数字或以十进制表示的数字的字符串的表达式。不支持二进制、八进制和十六进制表示的数字。前导零将被删除。
返回值
Float32
或Float64
数据类型的浮点值。- 函数使用向零舍入的方式,即截断数字的小数位。
- 函数对于 NaN 和 Inf 参数的行为是未定义的。在使用这些函数时,请注意数值转换问题。
示例
SELECT toFloat32('16'), toFloat64(8.8);
┌─toFloat32('16')─┬─toFloat64(8.8)─┐
│ 16 │ 8.8 │
└─────────────────┴────────────────┘
# toDate
将参数转换为 Date 数据类型。如果参数是 DateTime 或 DateTime64,则截断时间部分,只保留日期部分:
SELECT now() AS x, toDate(x)
┌───────────────────x─┬─toDate(now())─┐
│ 2022-12-30 13:44:17 │ 2022-12-30 │
└─────────────────────┴───────────────┘
示例
- 如果参数是字符串,则解析为 Date 或 DateTime。如果解析为 DateTime,则使用日期部分:
SELECT toDate('2022-12-30 01:02:03') AS x, toTypeName(x)
┌──────────x─┬─toTypeName(toDate('2022-12-30 01:02:03'))─┐
│ 2022-12-30 │ Date │
└────────────┴───────────────────────────────────────────┘
SELECT toDate('2022-12-30') AS x, toTypeName(x)
┌──────────x─┬─toTypeName(toDate('2022-12-30'))─┐
│ 2022-12-30 │ Date │
└────────────┴──────────────────────────────────┘
- 如果参数是数字,并且看起来像是 UNIX 时间戳(大于 65535),则将其解释为 DateTime,然后在当前时区将其截断为 Date。时区参数可以作为函数的第二个参数指定。截断为 Date 取决于时区:
SELECT now() AS current_time,
toUnixTimestamp(current_time) AS ts,
toDateTime(ts) AS time_Amsterdam,
toDateTime(ts, 'Pacific/Apia') AS time_Samoa,
toDate(time_Amsterdam) AS date_Amsterdam,
toDate(time_Samoa) AS date_Samoa,
toDate(ts) AS date_Amsterdam_2,
toDate(ts, 'Pacific/Apia') AS date_Samoa_2 FORMAT Vertical;
Row 1:
──────
current_time: 2023-11-14 10:37:49
ts: 1699929469
time_Amsterdam: 2023-11-14 10:37:49
time_Samoa: 2023-11-14 15:37:49
date_Amsterdam: 2023-11-14
date_Samoa: 2023-11-14
date_Amsterdam_2: 2023-11-14
date_Samoa_2: 2023-11-14
上面的示例演示了相同的 UNIX 时间戳在不同时区中可以解释为不同的日期。
如果参数是一个数字,并且小于 65536,则将其解释为自 1970-01-01(第一个 UNIX 日)以来的天数,并转换为 Date。它对应于
Date
数据类型的内部数值表示。示例:SELECT toDate(12345)
┌─toDate(12345)─┐ │ 2003-10-20 │ └───────────────┘
此转换不依赖于时区。
如果参数不适合 Date 类型的范围,则结果是实现定义的行为,可能会饱和到最大支持的日期或溢出:
SELECT toDate(10000000000.)
┌─toDate(10000000000.)─┐ │ 2106-02-07 │ └──────────────────────┘
函数
toDate
还可以以其他形式编写:SELECT now() AS time, toDate(time)
┌──────────time───────┬─────toDate(now()───┐ │ 2022-12-30 13:54:58 │ 2022-12-30 │ └─────────────────────┴────────────────────┘
# toDateTime64
将参数转换为 DateTime64 数据类型。
toDateTime64(expr, scale, [timezone])
参数
expr
— 值。字符串、UInt32、Float 或 DateTime。scale
- 刻度(精度):10 秒。有效范围:[ 0 : 9 ]。- 精度
timezone
- 指定的 datetime64 对象的时区。
返回值
- 一个带有亚秒精度的日历日期和时间。
- 类型:DateTime64。
示例
值在范围内:
SELECT toDateTime64('1955-01-01 00:00:00.000', 3) AS value, toTypeName(value);
┌───────────────────value─┬─toTypeName(toDateTime64('1955-01-01 00:00:00.000', 3)) ─┐ │ 1955-01-01 00:00:00.000 │ DateTime64(3) │ └─────────────────────────┴─────────────────────────────────────────────────────────┘
作为带有精度的十进制数:
SELECT toDateTime64(1546300800.000, 3) AS value, toTypeName(value);
┌───────────────────value─┬─toTypeName(toDateTime64(1546300800., 3)) ─┐ │ 2019-01-01 00:00:00.000 │ DateTime64(3) │ └─────────────────────────┴───────────────────────────────────────────┘
没有小数点时,仍然将值视为以秒为单位的 Unix 时间戳:
SELECT toDateTime64(1546300800000, 3) AS value, toTypeName(value);
┌───────────────────value─┬─toTypeName(toDateTime64(1546300800000, 3))─┐ │ 2299-12-31 23:59:59.000 │ DateTime64(3) │ └─────────────────────────┴────────────────────────────────────────────┘
使用
timezone
:SELECT toDateTime64('2019-01-01 00:00:00', 3, 'Asia/Istanbul') AS value, toTypeName(value);
┌───────────────────value─┬─toTypeName(toDateTime64('2019-01-01 00:00:00', 3, 'Asia/Istanbul'))─┐ │ 2019-01-01 00:00:00.000 │ DateTime64(3, 'Asia/Istanbul') │ └─────────────────────────┴─────────────────────────────────────────────────────────────────────┘
# toDecimal
将 value
转换为具有精度 S
的 Decimal (opens new window) 数据类型。value
可以是数字或字符串。S
(精度)参数指定小数位数。
toDecimal32(value, S)
toDecimal64(value, S)
toDecimal128(value, S)
toDecimal256(value, S)
参数
expr
— 表达式,返回字符串数据类型的值。ClickHouse 期望十进制数的文本表示形式。例如,'1.111'
。S
— 精度,结果值中的小数位数。
返回值
(Decimal(P,S))
数据类型的值。该值包含:- 具有
S
位小数的数字,如果 ClickHouse 将输入字符串解释为数字。
示例
SELECT toDecimal32(toString(1.111), 2) AS val, toTypeName(val);
┌──val─┬─toTypeName(toDecimal32(toString(1.111), 2))─┐
│ 1.11 │ Decimal(9, 2) │
└──────┴─────────────────────────────────────────────┘
# toString
用于在数字、字符串(但不包括固定字符串)、日期和带有时间的日期之间进行转换的函数。所有这些函数都接受一个参数。
- 在转换为或从字符串时,将使用与 TabSeparated 格式(以及几乎所有其他文本格式)相同的规则对值进行格式化或解析。如果无法解析字符串,则会抛出异常并取消请求。
- 在将日期转换为数字或反之时,日期对应于自 Unix 纪元开始以来的天数。在将带有时间的日期转换为数字或反之时,日期与时间对应于自 Unix 纪元开始以来的秒数。
- toDate/toDateTime 函数的日期和带有时间的日期的格式定义如下:
YYYY-MM-DDYYYY-MM-DD hh:mm:ss
- 作为例外,如果从 UInt32、Int32、UInt64 或 Int64 数值类型转换为 Date,并且数字大于或等于 65536,则该数字将被解释为 Unix 时间戳(而不是天数),并四舍五入为日期。这允许支持常见的写法
toDate(unix_timestamp)
,否则将导致错误,并需要编写更繁琐的toDate(toDateTime(unix_timestamp))
。 - 日期和日期与时间之间的转换按照自然方式进行:添加空时间或删除时间。
- 数值类型之间的转换使用与 C++ 中不同数值类型之间的赋值相同的规则。
示例
SELECT now() AS ts,
time_zone,
toString(ts) AS str_tz_datetime
FROM system.time_zones
WHERE time_zone LIKE 'Europe%'LIMIT 10
┌──────────────────ts─┬─time_zone─────────┬─str_tz_datetime─────┐
│ 2023-11-14 10:42:16 │ Europe/Amsterdam │ 2023-11-14 10:42:16 │
│ 2023-11-14 10:42:16 │ Europe/Andorra │ 2023-11-14 10:42:16 │
│ 2023-11-14 10:42:16 │ Europe/Astrakhan │ 2023-11-14 10:42:16 │
│ 2023-11-14 10:42:16 │ Europe/Athens │ 2023-11-14 10:42:16 │
│ 2023-11-14 10:42:16 │ Europe/Belfast │ 2023-11-14 10:42:16 │
│ 2023-11-14 10:42:16 │ Europe/Belgrade │ 2023-11-14 10:42:16 │
│ 2023-11-14 10:42:16 │ Europe/Berlin │ 2023-11-14 10:42:16 │
│ 2023-11-14 10:42:16 │ Europe/Bratislava │ 2023-11-14 10:42:16 │
│ 2023-11-14 10:42:16 │ Europe/Brussels │ 2023-11-14 10:42:16 │
│ 2023-11-14 10:42:16 │ Europe/Bucharest │ 2023-11-14 10:42:16 │
└─────────────────────┴───────────────────┴─────────────────────┘
# parseDateTime()
根据 MySQL 格式字符串将字符串转换为 DateTime。该函数是函数 formatDateTime 的相反操作。
parseDateTime(str, format[, timezone])
参数
str
— 要解析的字符串format
— 格式字符串timezone
— 时区。可选。
返回值
- 根据 MySQL 风格的格式字符串从输入字符串解析出的 DateTime 值。
支持的格式说明符
- 所有在 formatDateTime 中列出的格式说明符,除了:
- %Q:季度(1-4)
示例
SELECT parseDateTime('2021-01-04+23:00:00', '%Y-%m-%d+%H:%i:%s')
┌─parseDateTime('2021-01-04+23:00:00', '%Y-%m-%d+%H:%i:%s')─┐
│ 2021-01-04 23:00:00 │
└───────────────────────────────────────────────────────────┘