12.2 식 평가 형식 변환
연산자가 다른 유형의 피연산자와 함께 사용되면 피연산자의 호환성을 위해 형식 변환이 발생합니다. 일부 변환은 암시 적으로 발생합니다. 예를 들어, MySQL에서 필요에 따라 숫자가 문자열 (또는 그 반대)로 자동 변환됩니다.
mysql> SELECT 1+'1';
-> 2 mysql> SELECT CONCAT(2,' test');
-> '2 test'
또한 CAST()
함수를 명시 적으로 사용하여 숫자를 문자열로 변환 할 수 있습니다. CONCAT()
함수는 문자열 인수가 요구되기 때문에 사용하면 암시 적으로 변환이 발생합니다.
mysql>SELECT 38.8, CAST(38.8 AS CHAR);
-> 38.8, '38 .8 ' mysql>SELECT 38.8, CONCAT(38.8);
-> 38.8, '38 .8 '
문자 세트의 숫자에서 문자열로 암시 적 변환에 대해 설명하고 CREATE TABLE ... SELECT
문에 적용되는 수정 된 규칙은이 섹션 뒷부분을 참조하십시오.
다음 규칙은 비교 연산시에 어떻게 변환이 발생하는지에 대해 설명합니다.
NULL
-safe<=>
등가 비교 연산자의 경우를 제외하고는 하나 또는 두 개의 인수가NULL
의 경우, 비교 결과도NULL
입니다.NULL <=> NULL
의 경우, 결과가 true가됩니다. 변환 할 필요가 없습니다.비교 연산의 두 인수가 문자열이면 문자열로 비교됩니다.
모두의 인수가 정수의 경우, 정수로 비교됩니다.
16 진수 값이 숫자와 비교되지 않는 경우는 바이너리 문자열로 처리됩니다.
인수 중 하나가
TIMESTAMP
또는DATETIME
컬럼 한편이 정수의 경우는 비교가 실행되기 전에 상수가 타임 스탬프로 변환됩니다. 이것은 ODBC에 의해 준수하기 위해 실행됩니다. 이것은IN()
에 인수는 실행되지 않습니다. 만약을 위해, 비교를 할 때는 항상 완전한 날짜 시간, 날짜 또는 시간 문자열을 사용하십시오. 예를 들어, 날짜 또는 시간 값과 함께BETWEEN
을 사용했을 때의 결과를 최적화하려면CAST()
를 사용하여 명시 적으로 값을 원하는 데이터 형식으로 변환합니다.테이블 (복수 가능)에서 단 일행 서브 쿼리는 상수로 간주되지 않습니다. 예를 들어, 서브 쿼리에서
DATETIME
값과 비교하는 정수를 반환하는 경우 비교가 두 개의 정수로 실행됩니다. 정수는 시간 값은 변환되지 않습니다. 피연산자를DATETIME
값으로 비교하려면CAST()
를 사용하여 명시 적으로 서브 쿼리의 값을DATETIME
으로 변환합니다.인수 중 하나가 10 진수의 경우 비교는 다른 인수에 따라 달라집니다. 기타 인수가 10 진수 또는 정수 값의 경우, 인수는 10 진수 값으로 비교되고 다른 인자가 부동 소수점 값의 경우, 인수는 부동 소수점 값으로 비교됩니다.
다른 모든 경우에는, 인수는 부동 소수점 (실수) 숫자로 비교됩니다.
다른 시간 형식으로 값을 변환 내용은 섹션 11.3.7 "날짜 및 시간 형식 간의 변환" 을 참조하십시오.
다음 예제는 비교 연산에서 문자열에서 숫자로 변환을 보여줍니다.
mysql>SELECT 1 > '6x';
-> 0 mysql>SELECT 7 > '6x';
-> 1 mysql>SELECT 0 > 'x6';
-> 0 mysql>SELECT 0 = 'x6';
-> 1
문자열 컬럼과 숫자와 비교, MySQL은 컬럼에 인덱스를 사용하여 값을 빠르게 검색 할 수 없습니다. str_col
이 인덱스가 붙은 문자열 컬럼 인 경우 다음 문에서 검색을 수행 할 때 인덱스를 사용할 수 없습니다.
SELECT * FROM tbl_name
WHERE str_col
= 1;
그 이유는 '1'
, ' 1'
, '1a'
처럼 값 1
로 변환 할 수있는 다양한 문자열이 있기 때문입니다.
이 같은 수치는 부정확이기 때문에 부동 소수점 (또는 부동 소수점 숫자로 변환 된 값)을 사용하는 비교는 대략적인 것입니다. 이는 일관성없는 결과가 나타날 수 있습니다.
mysql>SELECT '18015376320243458' = 18015376320243458;
-> 1 mysql>SELECT '18015376320243459' = 18015376320243459;
-> 0
이 같은 결과는 53 비트의 정밀도 밖에없는 부동 소수점 값이 변환되어 반올림의 대상이되기 위해서는 발생할 수 있습니다.
mysql> SELECT '18015376320243459'+0.0;
-> 1.8015376320243e +16
또한 문자열에서 부동 소수점으로 변환 및 정수에서 부동 소수점으로 변환은 반드시 동일하게 발생하는 것은 아닙니다. 정수는 CPU에 의해 부동 소수점으로 변환 될 가능성이 있습니다. 한편, 문자열은 부동 소수점 곱셈을 수반 연산 1 자리 씩 변환됩니다.
표시되는 결과는 시스템에 따라 다르며, 컴퓨터 아키텍처와 컴파일러 버전 등의 요인 또는 최적화 수준의 영향을받을 가능성이 있습니다. 이러한 문제를 해결하는 방법 중 하나는 값이 암묵적으로 부동 소수점 값으로 변환됩니다 않도록 CAST()
를 사용하는 것입니다.
mysql> SELECT CAST('18015376320243459' AS UNSIGNED) = 18015376320243459;
-> 1
부동 소수점 비교에 대한 자세한 내용은 섹션 B.5.5.8 "부동 소수점 값 문제" 를 참조하십시오.
MySQL 5.6에서는 서버에 dtoa
가 포함되어 있습니다. 이것은 문자열 또는 DECIMAL
값과 근사치 ( FLOAT
/ DOUBLE
)의 수치 사이의 변환을 개선하기위한 기초를 제공하는 변환 라이브러리입니다.
Unix와 Windows 간의 변환 다름이 제거 된 플랫폼간에 일관된 변환 결과입니다.
이전의 결과에 충분한 정밀도가 없었던 경우 (IEEE의 한계에 가까운 값 등)의 정확한 값을 표시합니다.
최대한의 정밀도를 가진 문자열 형식의 숫자 변환.
dtoa
의 정확도는 항상 표준 C 라이브러리 함수의 정확도와 같거나 그 이상입니다.
이 라이브러리에서 생성 된 변환은 dtoa
이외의 결과와는 다를 수 있기 때문에 이전의 결과에 의존하는 어플리케이션과의 호환성이 유지되지 않을 가능성이 있습니다. 예를 들어, 이전의 변환에서 특정 정확한 결과에 의존하는 응용 프로그램은 추가 정밀도에 대응하도록 조정이 필요할 수 있습니다.
dtoa
라이브러리는 다음의 특성을 사용하여 변환이 제공됩니다. D
는 DECIMAL
또는 문자열 표현을 포함한 값을 나타내고, F
는 네이티브 바이너리 (IEEE) 형식의 부동 소수점 수를 나타냅니다.
F
->D
변환은 최대한의 정밀도로 실행되며 읽을 때F
가 생성되는 가장 짧은 문자열로D
를 반환하고 IEEE에서 지정되는 네이티브 바이너리 형식으로 가장 가까운 값으로 반올림됩니다 .D
->F
의 변환은F
가 입력 된 10 진수 문자열D
에 가장 가까운 네이티브 바이너리 숫자가되도록 실행됩니다.
F
가 -inf
+ +inf
또는 NaN
의 경우를 제외하고 이러한 특성은 F
-> D
-> F
의 변환이 가역적임을 암시하고 있습니다. 후자의 값은 SQL 표준에서는 FLOAT
또는 DOUBLE
잘못된 값으로 정의되어 있기 때문에 지원되지 않습니다.
D
-> F
-> D
변환은 D
가 15 자리 이하의 정밀도를 사용하여 비정규 값 ( -inf
+ +inf
또는 NaN
)하지 않을 수 가역위한 충분 조건입니다. D
의 정밀도가 15 자리보다 큰 경우에도 변환이 가역적 인 경우도 있지만 항상 해당한다고는 할 수 없습니다.
MySQL 5.6에서는 암묵적으로 수치 또는 시간 값을 문자열로 변환하면 character_set_connection
및 collation_connection
시스템 변수에서 결정된 문자 집합 및 정렬 순서를 포함한 값이 생성됩니다. (일반적으로 이러한 변수는 SET NAMES
를 사용하여 설정됩니다. 연결 문자 세트 내용은 섹션 10.1.4 "연결 문자 집합 및 정렬 순서" 를 참조하십시오.)
즉, 연결 문자 집합을 binary
로 설정되어있는 경우를 제외하고 이러한 변환은 (비 바이너리) 문자열 ( CHAR
, VARCHAR
또는 LONGTEXT
값)가 생성됩니다. 이 경우, 변환의 결과는 이진 문자열 ( BINARY
, VARBINARY
또는 LONGBLOB
값)입니다.
정수 식에서는 식의 평가에 관한 위의 비고는 식의 할당은 약간 다르게 적용됩니다. 다음과 같은 명령문의 예를 보여줍니다.
CREATE TABLE T SELECT integer_expr
;
이 경우 수식의 결과로 생성 된 컬럼의 테이블 형식은 정수 식의 길이에 따라 INT
또는 BIGINT
됩니다. 식의 최대 길이가 INT
에 맞지 않으면 대신 BIGINT
가 사용됩니다. 길이는 SELECT
결과 집합 메타 데이터 max_length
값에서 가져옵니다 ( 섹션 23.8.5 "C API 데이터 구조" 를 참조하십시오). 즉, 충분히 긴 수식을 사용하여 INT
대신 BIGINT
를 강제로 적용 할 수 있습니다.
CREATE TABLE t SELECT 000000000000000000000;