Spec-Zone.ru › MariaDB

Преобразование типов

Неявное преобразование типов происходит, когда 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 |
+--------------------+
Содержимое, воспроизведенное на этом сайте, является собственностью соответствующих владельцев, и это содержимое не предварительно проверяется MariaDB. Мнения, информация и мнения, выраженные в этом содержании, не обязательно отражают точку зрения MariaDB или любой другой стороны.

© 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/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API