# 类型转换函数

# toInt

将输入值转换为 Int 数据类型的值。该函数族包括:

  • toInt8(expr) — 转换为 Int8 数据类型的值。
  • toInt16(expr) — 转换为 Int16 数据类型的值。
  • toInt32(expr) — 转换为 Int32 数据类型的值。
  • toInt64(expr) — 转换为 Int64 数据类型的值。
  • toInt128(expr) — 转换为 Int128 数据类型的值。
  • toInt256(expr) — 转换为 Int256 数据类型的值。

参数

  • expr — 返回数字或以十进制表示的数字的字符串的表达式。不支持二进制、八进制和十六进制表示的数字。前导零将被删除。

返回值

  • Int8Int16Int32Int64Int128Int256 数据类型的整数值。
  • 函数使用向零舍入的方式,即截断数字的小数位。
  • 函数对于 NaN 和 Inf 参数的行为是未定义的。在使用这些函数时,请注意数值转换问题。

示例

SELECT toInt32(32), toInt16('16'), toInt8(8.8);
┌─toInt32(32)─┬─toInt16('16')─┬─toInt8(8.8)─┐
│          32168 │
└─────────────┴───────────────┴─────────────┘

# toUInt

将输入值转换为 UInt 数据类型的值。该函数族包括:

  • toUInt8(expr) — 转换为 UInt8 数据类型的值。
  • toUInt16(expr) — 转换为 UInt16 数据类型的值。
  • toUInt32(expr) — 转换为 UInt32 数据类型的值。
  • toUInt64(expr) — 转换为 UInt64 数据类型的值。
  • toUInt256(expr) — 转换为 UInt256 数据类型的值。

参数

  • expr — 返回数字或以十进制表示的数字的字符串的表达式。不支持二进制、八进制和十六进制表示的数字。前导零将被删除。

返回值

  • UInt8UInt16UInt32UInt64UInt256 数据类型的整数值。
  • 函数使用向零舍入的方式,即截断数字的小数位。
  • 函数对于负数参数、NaN 和 Inf 参数的行为是未定义的。例如,如果传递一个包含负数的字符串,例如 '-32',ClickHouse 将引发异常。在使用这些函数时,请注意数值转换问题。

示例

SELECT toUInt32(32), toUInt16('16'), toUInt8(8.8);
┌─toUInt32(32)─┬─toUInt16('16')─┬─toUInt8(8.8)─┐
│           32168 │
└──────────────┴────────────────┴──────────────┘

# toFloat

将输入值转换为 Float 数据类型的值。该函数族包括:

  • toFloat32(expr) — 转换为 Float32 数据类型的值。
  • toFloat64(expr) — 转换为 Float64 数据类型的值。

参数

  • expr — 返回数字或以十进制表示的数字的字符串的表达式。不支持二进制、八进制和十六进制表示的数字。前导零将被删除。

返回值

  • Float32Float64 数据类型的浮点值。
  • 函数使用向零舍入的方式,即截断数字的小数位。
  • 函数对于 NaN 和 Inf 参数的行为是未定义的。在使用这些函数时,请注意数值转换问题。

示例

SELECT toFloat32('16'), toFloat64(8.8);
┌─toFloat32('16')─┬─toFloat64(8.8)─┐
│              168.8 │
└─────────────────┴────────────────┘

# toDate

将参数转换为 Date 数据类型。如果参数是 DateTime 或 DateTime64,则截断时间部分,只保留日期部分:

SELECT now() AS x, toDate(x)
┌───────────────────x─┬─toDate(now())─┐
│ 2022-12-30 13:44:172022-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-30Date                                      │
└────────────┴───────────────────────────────────────────┘
SELECT toDate('2022-12-30') AS x, toTypeName(x)
┌──────────x─┬─toTypeName(toDate('2022-12-30'))─┐
│ 2022-12-30Date                             │
└────────────┴──────────────────────────────────┘
  • 如果参数是数字,并且看起来像是 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:582022-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 转换为具有精度 SDecimal (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.11Decimal(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 │
└───────────────────────────────────────────────────────────┘