CSV 데이터에서 MySQL로드 NULL 값


167

쉼표로 구분 된 3-4 열의 숫자 값을 포함 할 수있는 파일이 있습니다. 빈 필드는 행 끝에있을 때 예외로 정의됩니다.

1,2,3,4,5
1,2,3,,5
1,2,3

다음 테이블은 MySQL에서 생성되었습니다.

+ ------- + -------- + ------ + ----- + --------- + ------- +
| 분야 | 타입 | 널 | 키 | 기본 | 추가 |
+ ------- + -------- + ------ + ----- + --------- + ------- +
| 하나 | int (1) | 예 | | NULL | |
| 두 | int (1) | 예 | | NULL | |
| 세 | int (1) | 예 | | NULL | |
| 네 | int (1) | 예 | | NULL | |
| 다섯 | int (1) | 예 | | NULL | |
+ ------- + -------- + ------ + ----- + --------- + ------- +

MySQL LOAD 명령을 사용하여 데이터를로드하려고합니다.

LOAD DATA INFILE '/tmp/testdata.txt' INTO TABLE moo FIELDS 
TERMINATED BY "," LINES TERMINATED BY "\n";

결과 테이블 :

+ ------ + ------ + ------- + ------ + ------ +
| 하나 | 두 | 세 | 네 | 다섯 |
+ ------ + ------ + ------- + ------ + ------ +
| 1 | 2 | 3 | 4 | 5 |
| 1 | 2 | 3 | 0 | 5 |
| 1 | 2 | 3 | NULL | NULL |
+ ------ + ------ + ------- + ------ + ------ +

문제는 원시 데이터에서 필드가 비어 있고 정의되지 않은 경우 어떤 이유로 MySQL은 열 기본값 (NULL)을 사용하지 않고 0을 사용한다는 사실에 있습니다. 필드가 모두 누락 된 경우 NULL이 올바르게 사용됩니다.

불행히도,이 단계에서 NULL과 0을 구별 할 수 있어야 도움을 얻을 수 있습니다.

고마워요

편집하다

SHOW WARNINGS의 출력 :

+ --------- + ------ + -------------------------------- ------------------------ +
| 레벨 | 코드 | 메시지 |
+ --------- + ------ + -------------------------------- ------------------------ +
| 경고 | 1366 | 잘못된 정수 값 : 2 행의 '4'열에 대해 ''|
| 경고 | 1261 | 행 3에 모든 열에 대한 데이터가 포함되어 있지 않습니다 |
| 경고 | 1261 | 행 3에 모든 열에 대한 데이터가 포함되어 있지 않습니다 |
+ --------- + ------ + -------------------------------- ------------------------ +

데이터 스키마 변경과 함께 d6tstack 을 사용하여 실행하기 전에 모든 열을 정렬합니다 LOAD DATA. 데이터 스키마 변경에 대한 d6tstack SQL 예제 섹션을 참조하십시오 .
citynorman

답변:


193

이것은 당신이 원하는 것을 할 것입니다. 네 번째 필드를 로컬 변수로 읽은 다음 로컬 변수가 빈 문자열을 포함하는 경우 실제 필드 값을 NULL로 설정합니다.

LOAD DATA INFILE '/tmp/testdata.txt'
INTO TABLE moo
FIELDS TERMINATED BY ","
LINES TERMINATED BY "\n"
(one, two, three, @vfour, five)
SET four = NULLIF(@vfour,'')
;

그것들이 모두 비어있는 경우, 변수를 모두 읽고 다음과 같이 여러 개의 SET 문을 갖습니다.

LOAD DATA INFILE '/tmp/testdata.txt'
INTO TABLE moo
FIELDS TERMINATED BY ","
LINES TERMINATED BY "\n"
(@vone, @vtwo, @vthree, @vfour, @vfive)
SET
one = NULLIF(@vone,''),
two = NULLIF(@vtwo,''),
three = NULLIF(@vthree,''),
four = NULLIF(@vfour,'')
;

이론적으로, 나는 가정합니다-그러나 그것은 모두 메모리에 있고 행 당 적은 양의 데이터 만 보유하므로 무한대 이미지라고 생각합니다. 문제가 될 수 있다고 생각되면 테스트해야합니다.
Duncan Lock

4
나는이 답변을 정말로 좋아한다. 사용자는 Excel 에서 ''CSV를 다운로드 할 때 ( 쿼리에 사용하여 ) 빈 문자열을 볼 수 있지만 업로드 는 CSS에서 처리 해야하는 것과 비교하여 null로 허용합니다 . 감사! IFNULL(Col,'')SELECT INTO OUTFILE\N
chrisan

9
날짜에 'NULLIF (STR_TO_DATE (@ date1, "% d / % m / % Y"), "0000-00-00")'을 사용했습니다.
Joaquín L. Robles

1
0변환 해야하는 0을 포함하는 csv 파일이 있습니다 NULL(문제의 데이터에 대해 0 값을 가질 수 없기 때문에). 0과 빈 문자열을 모두로 변환하는 방법은 NULL무엇입니까?
Paul Rougieux

0 값과 빈 문자열이 별도의 열에 있으면 빈 문자열에 대해 위의 작업을 수행하고 0에 대해 이와 같은 작업을 수행하십시오 nullif(@vone, 0).
Duncan Lock

136

MySQL 매뉴얼 은 말합니다 :

LOAD DATA INFILE로 데이터를 읽을 때 비어 있거나 누락 된 열은 ''로 업데이트됩니다. 열에 NULL 값이 필요한 경우 데이터 파일에 \ N을 사용해야합니다. 상황에 따라 문자 "NULL"을 사용할 수도 있습니다.

따라서 다음과 같이 공백을 \ N으로 바꿔야합니다.

1,2,3,4,5
1,2,3,\N,5
1,2,3

3
팁 주셔서 감사합니다-원시 소스 데이터를 편집하는 데 회의적이지만 이것이 유일한 방법이라면 시도해 볼 것입니다.
Spiros

7
나는 당신의 회의론을 이해합니다. 아무도 원시 데이터를 편집하는 것을 좋아하지 않습니다. 그러나 1 분 동안 생각하면 NULL과 빈 문자열을 구별하는 방법이 있어야합니다. 빈 항목을 NULL로 변환해야하는 경우 빈 문자열에 대한 특수 시퀀스가 ​​필요합니다. LOAD DATA INFILE '/tmp/testdata.txt'INTO TABLE moo TREAT
BLANKS

2
당신이있는 경우 OK,하지만 Fields enclosed by: ""\N""name",\N,"stuff"
조나단

3
적어도 "phpMyAdmin 3.5.5"에 대해 어떤 스타일 \N도 나타내는 것으로 인정 되지 않음을 확인할 수 있습니다 NULL. 대신 NULL이 예와 같이을 사용하십시오 ."name","age",NULL,"other","stuff"
Jonathon

1
MySQL 5.5.46-0 + deb8u1이 있습니다. NULL과 \ N을 모두 시도했지만 \ N 만 우리를 위해 일했습니다.
raphael75

6

데이터베이스 구성에 따라 동작이 다릅니다. 엄격 모드에서는 오류가 발생하고 그렇지 않으면 경고가 발생합니다. 데이터베이스 구성을 식별하기 위해 다음 쿼리를 사용할 수 있습니다.

mysql> show variables like 'sql_mode';

감사! 어제 프로덕션 서버에서 가져온 빈 열이있는 CSV를 가져 오는 것이 새로운 로컬 설치에서 작동하지 않는 이유를 알아 내려고 노력하고있었습니다. 이것이 내 대답이었습니다!
Emma Burrows

3

빈 칸 항목을 \ N으로 바꾸려면 입력 CSV를 전처리하십시오.

정규식에서 시도 : s / ,, /, \ n, / g 및 s /, $ /, \ N / g

행운을 빕니다.


1
이 정규 표현식은 부분적으로 작동하며 순차적 공백 항목을 해결하지 않습니다. 예를 들어, \ n ,, \ n, 두 번 실행하면 사용할 수 있어야합니다
ievgen

1
답변과 이전 의견을 요약합니다. 다음 순서대로 나를 위해 일했습니다 : sed -i 's / ,, /, \ N / g'$ file, sed -i 's / ,, /, / g'$ file, sed -i 's / \ N, $ / \ N / g '$ file,
Omar Khazamov

이 작업을 수행하고 싶지만이 정규식을 어떻게 실행하고 있는지 확실하지 않습니다. MySQL을 사용하여 파일에 대해 이것을 실행하는 경우 이것이 최선의 해결책입니다. 그러나 당신은 말하지 않으며 불가능한 일을하는 방법을 인터넷 검색하는 데 많은 시간을 보내고 싶지 않습니다.
DonkeyKong

1

(variable1, @ variable2, ..) SET variable2 = nullif (@ variable2, ''또는 '') >> 모든 조건을 넣을 수 있습니다


0

변수 표시

Show variables like "`secure_file_priv`";

참고 : csv 파일을 위 명령으로 지정된 위치에 보관하십시오.

create table assessments (course_code varchar(5),batch_code varchar(7),id_assessment int, assessment_type varchar(10), date int , weight int);

참고 : 여기서 ' date'열에는 csv 파일에 빈 값이 있습니다.

LOAD DATA INFILE 'C:/ProgramData/MySQL/MySQL Server 8.0/Uploads/assessments.csv' 
INTO TABLE assessments
FIELDS TERMINATED BY ',' 
OPTIONALLY ENCLOSED BY '' 
LINES TERMINATED BY '\n' 
IGNORE 1 ROWS 
(course_code,batch_code,id_assessment,assessment_type,@date,weight)
SET date = IF(@date = '', NULL, @date);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.