MySQL и тайпкастинг

Рубрика: MySQL | 17 September 2007, 15:36 | Vadim Voituk

Так как MySQL производит автоматическую конверсию типов в тектсе SQL-запросов, расскажу немного о том, как можно этой конверсией управлять.
Предположим у нас есть 2 одинаковых даты, но в разных форматах:
’2007-07-01′ и ’20070701′.
Необходимо средствами БД (например в SQL-запросе) ставнить их на равенство:

Очевидно, что простым сравнением тут не обойдешься:
SELECT '2007-07-01' = '20070701'
#= 0

В данном случае MySQL считает оба значения строками и сравнивает их лексикографически. В итоге получаем 0.

Для указания того, что мы работаем не со строками а с датами, необходимо выполнить конверсию типов (или тайпкастинг).
Делается это с помощью функции CAST():
SELECT CAST('2007-07-01' AS DATE) = CAST('20070701' AS DATE);
#= 1

В случае когда MySQL “знает” тип одного из операндов, второй приводится к этому типу автоматически:
SELECT '2007-07-01' = CAST('20070701' AS DATE);
#= 1

Аналогичная ситуация наблюдается если слева будет указано поле таблицы – в таком случае второй операнд будет приводиться к типу этого поля.
Например:
SELECT myDatField FROM myTable LIMIT 1\G
myDatField=2007-07-01

SELECT myDatField=20070101 AS res FROM myTable LIMIT 1\G
res=1

Но такое поведение наблюдается только в случае, если не происходит автоматическа конвертация из CHAR в INT и наоборот.
Пример:
SELECT '20070701'=CAST('2007-07-01' AS DATE);
#=0
# но в то же время
SELECT '2007-07-01'=CAST('20070701' AS DATE)
#=1

Или же ещё один пример (IMHO более презентабельный):

SELECT CAST('20070101' AS DATE)=CAST('20070101' AS UNSIGNED INTEGER);
#= 0
# Тут вопросов быть не должно, т.к. слева получаем что-то вроде "2007-01-01"
# но при этом
SELECT CAST('10' AS SIGNED INTEGER)=CAST('10' AS CHAR);
#= 1
# тут уже имеем автоматическую CHAR<->INT конверсию

Стоит добавить что в результате конверсии типов (как явной так и неявной) возможно “выпадание” индекса из сценария запроса, что приводит к существенному понижению производительности.

Комментариев: 2

2 Responses to “MySQL и тайпкастинг”

Комментарии:

  1. Скакунов Александр

    Занимательно.
    Реально приходится обращать внимание на такие тонкости?

  2. vadim

    Про то, что в результате тайпкастинга из запроса выпадает индекс, уже и говорить неприлично – в сети об этом написано-перенаписано (да и по explain-у можно увидеть).
    А вот в случае когда приходится сравнивать данные в разных форматах (даты), на это стоит ображать внимаение, т.к. не всегда параметрическое значение интерпретируется нужным образом. В принципе такое бывает нечасто, но бывает.

Leave a Reply