[SQL] 분할 다중 행으로 SQL 열의 값을 구분
SQL분할 다중 행으로 SQL 열의 값을 구분
난 정말 여기에 몇 가지 조언처럼, 내가 SQL에 Exchange 2007에서 메시지 추적 로그를 삽입하는 작업을하고 몇 가지 배경 정보를 제공하는 것입니다. 우리는 내가 SQL 테이블에 데이터를 삽입 할 대량 삽입 문을 사용하고 하루에 수백만 개의 행에 수백만 달러를 가지고.
나는 라이브 테이블에 데이터가 MERGE에서 임시 테이블에 사실 나는 실제로 대량 삽입에서 다음이 특정 필드 그렇지 않으면 값 따옴표 등을 가지고 시험 문제를 분석입니다.
이렇게하면받는 사람 주소의 열이로 구분 럼 식별자 필드가 있다는 사실을 제외하고는 잘 작동한다; 많은 이메일 수신자가있을 수있는 캐릭터, 그리고 긴 때로는 믿을 수 없을 수 있습니다.
이 칼럼을하고 다른 테이블에 삽입 될 여러 행에 값을 분할하고 싶습니다. 문제는 나도 내가 원하는 방식으로 작업이 너무 오래 여부를 취하고 노력하고 무엇이다.
이 예제 데이터를 가지고 :
message-id recipient-address
2D5E558D4B5A3D4F962DA5051EE364BE06CF37A3A5@Server.com user1@domain1.com
E52F650C53A275488552FFD49F98E9A6BEA1262E@Server.com user2@domain2.com
4fd70c47.4d600e0a.0a7b.ffff87e1@Server.com user3@domain3.com;user4@domain4.com;user5@domain5.com
내 수신자 테이블에 다음과 같이이 포맷 할 싶습니다 :
message-id recipient-address
2D5E558D4B5A3D4F962DA5051EE364BE06CF37A3A5@Server.com user1@domain1.com
E52F650C53A275488552FFD49F98E9A6BEA1262E@Server.com user2@domain2.com
4fd70c47.4d600e0a.0a7b.ffff87e1@Server.com user3@domain3.com
4fd70c47.4d600e0a.0a7b.ffff87e1@Server.com user4@domain4.com
4fd70c47.4d600e0a.0a7b.ffff87e1@Server.com user5@domain5.com
아무도 내가이 일에 대해 갈 수있는 방법에 대한 아이디어가 있습니까?
나는이 점에서 시도 그래서 내가 꽤 잘 PowerShell을 알고 있지만, 심지어 28K 기록에 foreach 루프 프로세스에 영원히했다, 나는 가능한 한 효율적으로 빨리 실행됩니다 뭔가를 /이 필요합니다.
감사!
해결법
-
==============================
1.첫째, 분할 함수를 만들 :
첫째, 분할 함수를 만들 :
CREATE FUNCTION dbo.SplitStrings ( @List NVARCHAR(MAX), @Delimiter NVARCHAR(255) ) RETURNS TABLE AS RETURN (SELECT Number = ROW_NUMBER() OVER (ORDER BY Number), Item FROM (SELECT Number, Item = LTRIM(RTRIM(SUBSTRING(@List, Number, CHARINDEX(@Delimiter, @List + @Delimiter, Number) - Number))) FROM (SELECT ROW_NUMBER() OVER (ORDER BY s1.[object_id]) FROM sys.all_objects AS s1 CROSS APPLY sys.all_objects) AS n(Number) WHERE Number <= CONVERT(INT, LEN(@List)) AND SUBSTRING(@Delimiter + @List, Number, 1) = @Delimiter ) AS y); GO
이제 당신은 단순히으로 추정 할 수 있습니다 :
SELECT s.[message-id], f.Item FROM dbo.SourceData AS s CROSS APPLY dbo.SplitStrings(s.[recipient-address], ';') as f;
또한 나는 열 이름에 대시를 참을 수 없어하는 것이 좋습니다. 그것은 당신이 항상 [대괄호]에 넣어해야 의미합니다.
-
==============================
2.SQL 서버 2016은 이전 솔루션과 유사한 새 테이블 함수 string_split ()를 포함한다.
SQL 서버 2016은 이전 솔루션과 유사한 새 테이블 함수 string_split ()를 포함한다.
유일한 요구 사항은로 설정 호환성 수준을 130 (2016 SQL 서버)
-
==============================
3.당신은 CROSS이 (SQL 서버 위 2016에서 사용할 수) (SQL 서버 2005 이상 가능) 및 STRING_SPLIT 기능을 적용 사용할 수 있습니다 :
당신은 CROSS이 (SQL 서버 위 2016에서 사용할 수) (SQL 서버 2005 이상 가능) 및 STRING_SPLIT 기능을 적용 사용할 수 있습니다 :
DECLARE @delimiter nvarchar(255) = ';'; -- create tables CREATE TABLE MessageRecipients (MessageId int, Recipients nvarchar(max)); CREATE TABLE MessageRecipient (MessageId int, Recipient nvarchar(max)); -- insert data INSERT INTO MessageRecipients VALUES (1, 'user1@domain.com; user2@domain.com; user3@domain.com'); INSERT INTO MessageRecipients VALUES (2, 'user@domain1.com; user@domain2.com'); -- insert into MessageRecipient INSERT INTO MessageRecipient SELECT MessageId, ltrim(rtrim(value)) FROM MessageRecipients CROSS APPLY STRING_SPLIT(Recipients, @delimiter) -- output results SELECT * FROM MessageRecipients; SELECT * FROM MessageRecipient; -- delete tables DROP TABLE MessageRecipients; DROP TABLE MessageRecipient;
결과 :
MessageId Recipients ----------- ---------------------------------------------------- 1 user1@domain.com; user2@domain.com; user3@domain.com 2 user@domain1.com; user@domain2.com
과
MessageId Recipient ----------- ---------------- 1 user1@domain.com 1 user2@domain.com 1 user3@domain.com 2 user@domain1.com 2 user@domain2.com
from https://stackoverflow.com/questions/11018076/splitting-delimited-values-in-a-sql-column-into-multiple-rows by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] 왜 SQL 서버는이 오류를 던지고있다 : 열 'ID'에 NULL 값을 삽입 할 수 없습니다? (0) | 2020.04.15 |
---|---|
[SQL] dataframe 기능 대 스파크 SQL 쿼리 (0) | 2020.04.15 |
[SQL] 2 개 날짜 매개 변수를 포함하는 가장 쉬운 사이의 날짜와 임시 테이블을 채우는 방법 및 (0) | 2020.04.15 |
[SQL] 어떻게 MySQL의에서 슬래시 (\)를 검색하려면? (\) 이스케이프 왜 요구되는 경우 (=)하지만처럼을 위해 필요하지? (0) | 2020.04.15 |
[SQL] 오라클의 CLOB 컬럼을 조회하는 방법 (0) | 2020.04.15 |