2009-04-14 2 views
1

이름 목록이 포함 된 열이 있습니다. 이름에서 첫 번째 (고유 한) 문자 만 선택해야합니다. 다음 쿼리는 꽤 잘 작동 비 UTF-8 문자의 경우 :첫 번째 문자의 고유 목록을 선택하는 방법 [MySQL]

그러나
SELECT DISTINCT LEFT(T1.Name, 1) AS firstLetter 

의 이름이 UTF-8 인코딩이 반환 문자로 시작 : -sign. UTF-8 문자열의 첫 문자 일뿐입니다.

미리 감사드립니다.

질문은 위의 열에서 첫 번째 문자를 올바르게 선택하는 방법입니다.

P .: 테이블 문자 집합은 utf8이고 데이터 정렬은 utf8_bin으로 설정되고 필드 문자 집합은 utf8이며 데이터 정렬은 utf8_turkish_ci로 설정됩니다.

답변

5

LEFT(str, 1)을하도록되어 당신이 뭔가를 할 수 있습니다 가장 왼쪽 문자, 가장 왼쪽이 아닌 바이트. 즉, 첫 번째 문자가 멀티 바이트 문자 인 경우에도 쿼리가 원하는 것을 수행하고 있음을 의미합니다.

연결/인코딩/글꼴/렌더링 문제로 인해 기호가 추측됩니다. 이 쿼리는 2 이상의 어떤 결과를 제공하는 경우 있도록 문자열, 소요 얼마나 많은 바이트

SELECT LENGTH(LEFT(T1.Name, 1)) AS charLength 

길이 반환을 시도,이 LEFT()이 멀티 바이트 문자를 반환 실제로는 것을 의미하고 문제는 쿼리 자체 너머 .

명령 줄에서 쿼리를 실행하는 경우 터미널에서 문자를 렌더링 할 수 없거나 그렇지 않으면 다른 곳에서 엉망이 된 것입니다. 스크립팅 언어를 사용하는 경우 해당 언어의 문자열 길이 및 ord() 함수를 사용하여 무슨 일이 일어나는지 알아보십시오.

편집 : 당신이 PHP를 사용하고 있기 때문에, 이것을 시도 :

예를 들어 결과가 this character은 다음 "0xC4 0x9E"를 받아야이다
//Store a character returned from the database in $unicodechar 
$unicodechar = $row[0]; 

//Now print out the value of each byte in the character 
for($i = 0; $i < strlen($unicodechar); $i++) 
{ 
    echo '0x' . dechex(ord($char[$i])) . ' '; 
} 
echo '\n'; 

합니다. 실제로 이런 종류의 것을 얻으면, PHP는 멀티 바이트 문자를 올바르게 가져오고, 문제는 웹 페이지 자체의 인코딩 (this W3C page 참조)이거나 브라우저/글꼴이 특정 문자를 렌더링 할 수 없다는 것입니다.

+0

맞아,이게 내가 의심하는 바야. 내 대답에 주석을보십시오. 그 동안 나는 LEFT도 시도했고 멀티 바이트 인식도합니다. –

+0

실제로 char의 길이를 2로 반환했습니다. 머리를 주셔서 감사합니다! // PHP를 사용하여 결과를 봅니다. – turezky

0

설명서에 따르면 하위 문자열 기능은 멀티 바이트 안전합니다. 나는 russion 데이터베이스로 시도했다. 이 트릭을 수행해야합니다

SELECT DISTINCT SUBSTRING(T1.Name, 1, 1) AS firstLetter FROM T1 
+0

불행히도, 그것은 잘 풀리지 않았다 : ( – turezky

+0

당신은 select with which with select?커맨드 라인 클라이언트는 일반적으로 기본 터미널에 따라 다르기 때문에 다중 바이트로 작동하지 않습니다. MySQL Query Browser 또는 그와 비슷한 것을 사용해보십시오. –

0

ORD 기능은 멀티 바이트 또는 기본 ASCII 모두 경우 가장 왼쪽 문자의 코드를 반환합니다.

SELECT DISTINCT ORD(T1.Name) AS firstCode 

다시 문자를 얻으려면, 당신은 다음과 같이 얻을 수 UTF-8 문자 집합 지정 CHAR 기능을 사용할 수 있습니다 :

SELECT DISTINCT CHAR(ORD(T1.NAME) USING utf8) as firstLetter