Преобразование типов
Неявное преобразование типов происходит, когда MariaDB использует операнды разных типов, чтобы сделать операнды совместимыми.
Лучшей практикой является не полагаться на неявное преобразование; вместо этого используйте CAST для явного преобразования типов.
Правила преобразования при сравнении
- Если один из аргументов равен NULL, результат сравнения равен NULL, за исключением случая использования оператора сравнения равенства с проверкой на NULL <=>.
- Если оба аргумента — целые числа, они сравниваются как целые числа.
- Если оба аргумента — строки, они сравниваются как строки.
- Если один аргумент — десятичное число, а другой — десятичное или целое число, они сравниваются как десятичные числа.
- Если один аргумент — десятичное число, а другой — число с плавающей точкой, они сравниваются как числа с плавающей точкой.
- Если один аргумент — строка, а другой — целое число, они сравниваются как десятичные числа. Это преобразование было добавлено в MariaDB 10.3.36. До версии 10.3.36 такая комбинация сравнивалась как числа с плавающей точкой, что не всегда работало хорошо для больших 64-битных целых чисел из-за возможной потери точности при преобразовании в двойную точность.
- Если шестнадцатеричный аргумент не сравнивается с числом, он обрабатывается как двоичная строка.
- Если константа сравнивается с TIMESTAMP или DATETIME, константа преобразуется в отметку времени, за исключением случаев использования в качестве аргумента функции IN.
- В других случаях аргументы сравниваются как числа с плавающей точкой или вещественные числа.
Обратите внимание, что если столбец со строковым типом данных сравнивается с числовым значением, MariaDB не будет использовать индекс по этому столбцу, так как существует множество альтернативных значений, которые могут быть равны (см. примеры ниже).
Примеры сравнения
Преобразование строки в число:
SELECT 15+'15'; +---------+ | 15+'15' | +---------+ | 30 | +---------+
Преобразование числа в строку:
SELECT CONCAT(15,'15'); +-----------------+ | CONCAT(15,'15') | +-----------------+ | 1515 | +-----------------+
Ошибки с числами с плавающей точкой:
SELECT '9746718491924563214' = 9746718491924563213; +---------------------------------------------+ | '9746718491924563214' = 9746718491924563213 | +---------------------------------------------+ | 1 | +---------------------------------------------+
Числовое эквивалентность строк:
SELECT '5' = 5; +---------+ | '5' = 5 | +---------+ | 1 | +---------+ SELECT ' 5' = 5; +------------+ | ' 5' = 5 | +------------+ | 1 | +------------+ SELECT ' 5 ' = 5; +--------------+ | ' 5 ' = 5 | +--------------+ | 1 | +--------------+ 1 row in set, 1 warning (0.000 sec) SHOW WARNINGS; +-------+------+--------------------------------------------+ | Level | Code | Message | +-------+------+--------------------------------------------+ | Note | 1292 | Truncated incorrect DOUBLE value: ' 5 ' | +-------+------+--------------------------------------------+
В результате вышеизложенного MariaDB не может использовать индекс при сравнении строки с числовым значением в примере ниже:
CREATE TABLE t (a VARCHAR(10), b VARCHAR(10), INDEX idx_a (a));
INSERT INTO t VALUES
('1', '1'), ('2', '2'), ('3', '3'),
('4', '4'), ('5', '5'), ('1', '5');
EXPLAIN SELECT * FROM t WHERE a = '3' \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: t
type: ref
possible_keys: idx_a
key: idx_a
key_len: 13
ref: const
rows: 1
Extra: Using index condition
EXPLAIN SELECT * FROM t WHERE a = 3 \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: t
type: ALL
possible_keys: idx_a
key: NULL
key_len: NULL
ref: NULL
rows: 6
Extra: Using where
Правила преобразования при арифметических операциях с двумя операндами
Неявное преобразование типов также происходит при арифметических операциях с двумя операндами (+,-,*,/). MariaDB выбирает минимальный тип данных, гарантированно подходящий для результата, и преобразует оба аргумента в тип данных результата.
Для сложения (+), вычитания (-) и умножения (*) тип данных результата выбирается следующим образом:
- Если один из аргументов — приблизительное число (float, double), результат — double.
- Если один из аргументов — строка (char, varchar, text), результат — double.
- Если один из аргументов — десятичное число, результат — decimal.
- Если один из аргументов — временной тип с ненулевой дробной частью секунды (time(N), datetime(N), timestamp(N)), результат — decimal.
- Если один из аргументов — временной тип с нулевой дробной частью секунды (time(0), date, datetime(0), timestamp(0)), результат может варьироваться между int, int unsigned, bigint или bigint unsigned, в зависимости от точной комбинации типов данных.
- Если оба аргумента — целые числа (tinyint, smallint, mediumint, bigint), результат может варьироваться между int, int unsigned, bigint или bigint unsigned, в зависимости от точных типов данных и их знаков.
Для деления (/) тип данных результата выбирается следующим образом:
- Если один из аргументов — приблизительное число (float, double), результат — double.
- Если один из аргументов — строка (char, varchar, text), результат — double.
- В противном случае результат — decimal.
Примеры арифметических операций
Обратите внимание, что вышеуказанные правила означают, что когда аргумент временного типа данных появляется в сложении или вычитании, он по умолчанию обрабатывается как число.
SELECT TIME'10:20:30' + 1; +--------------------+ | TIME'10:20:30' + 1 | +--------------------+ | 102031 | +--------------------+
Для выполнения временного сложения или вычитания используйте функции DATE_ADD() или DATE_SUB(), или выражение INTERVAL в качестве второго аргумента:
SELECT TIME'10:20:30' + INTERVAL 1 SECOND; +------------------------------------+ | TIME'10:20:30' + INTERVAL 1 SECOND | +------------------------------------+ | 10:20:31 | +------------------------------------+
SELECT "2.2" + 3; +-----------+ | "2.2" + 3 | +-----------+ | 5.2 | +-----------+ SELECT 2.2 + 3; +---------+ | 2.2 + 3 | +---------+ | 5.2 | +---------+ SELECT 2.2 / 3; +---------+ | 2.2 / 3 | +---------+ | 0.73333 | +---------+ SELECT "2.2" / 3; +--------------------+ | "2.2" / 3 | +--------------------+ | 0.7333333333333334 | +--------------------+
© 2023 MariaDB
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.
https://mariadb.com/kb/en/type-conversion/