2011-02-11 4 views
5

기존 표를 첫 번째 정규 양식 (가장 간단한 정규화 가능, 예 참조)으로 변환하고 싶습니다.기존 테이블을 정규화하는 T-SQL은 무엇입니까?

T-SQL이 이런 종류의 문제인지 알 수 있습니까? 많은 감사합니다!

enter image description here

이 업데이트는 답변을 아래에 시도

, 완벽하게 일했다. 대답을 테스트하는 단계는 다음과 같습니다.

  1. Microsoft SQL Management Studio를 시작하십시오.
  2. 아래 데이터로 테이블을 만듭니다.
  3. "고객"의 ID가 "기본 키"및 "ID"로 설정되어 있는지 확인하십시오.
  4. "주문"의 ID에 특수 설정 (외부 키)이 없는지 확인하십시오.
  5. 데이터베이스 다이어그램을 연 다음 "고객"테이블과 "주문"테이블간에 1 : * 관계를 만듭니다.
  6. "고객"테이블과 "주문"테이블에서 스크립트를 실행하면 데이터가 자동으로 정상적으로 자동으로 정상화됩니다.
  7. 방금 ​​가져온 플랫 .csv 파일에서 시작하여 정보를 데이터베이스의 정규화 된 형식으로 복사하려는 경우 매우 유용합니다.
+0

이미지 링크가 작동하지 않습니다. –

+0

필자는 이것이 현명한 리팩토링이지만 표준화가 아니라는 데 동의합니다. 기능상으로는'name '에 의존하지 않습니다. –

+0

이 질문에 대한 약간의 장난감 예라고 인정합니다. 전체 문제는 이것에 비해 좀 더 복잡합니다. – Contango

답변

4

:

+0

완벽 해, 나는 그것을 시도하고 완벽하게 일했다. – Contango

+1

왜 [주문] 주변에 괄호가 사용되었는지 궁금해했습니다. 이유를 설명해 주셔서 감사합니다. – Contango

0

일회용 프로세스 인 경우 먼저 .csv를 조작하고 기본 키를 포함하여 테이블을 형성해야합니다. 당신은 SQL 데이터베이스를 채울 때, 당신은 순수 TSQL 솔루션을 필요로하는 경우, 내가 같은 기본적인 일을 임시 테이블을 생성하고, 대신 .CSV의 임시 테이블에서 삽입합니다

SET IDENTITY_INSERT Customers ON 

INSERT Customers 
(
    ... 
) 
SELECT 
    ... 
FROM 
    openrowset(...) 

SET IDENTITY_INSERT Customers ON 



SET IDENTITY_INSERT Orders ON 

INSERT Orders 
(
    ... 
) 
SELECT 
    ... 
FROM 
    openrowset(...) 

SET IDENTITY_INSERT Orders ON 

를 사용합니다. 당신이 수입

INSERT INTO Customer (Name) 
SELECT DISTINCT f.Name 
FROM Flat_CSV_File f 
LEFT OUTER JOIN Customer c ON f.Name = c.Name 
WHERE c.Id IS NULL 

주문을 반복 한 경우 고객 테이블

INSERT INTO Customer (Name) 
SELECT DISTINCT Name 
FROM Flat_CSV_File 

시작

-- assuming that Id is an Identity column or has some default to generate keys. 
Insert Customer([Name]) 
Select Name 
From Flat_csv_file 
Group By Name 

Insert Order([Customer], [Description], Cost) 
Select C.Id, F.Description F.Cost 
From Customer As C 
    Join Flat_csv_file As F 
     On F.Name = C.Name 
+0

ID 삽입을 켜거나 끄는 과정을 수행 할 이유가 없습니다. 이것은 좋은 습관이 아닙니다. – HLGEM

4

가장 간단한 해결 방법은 가져 오기를 수행하는 쿼리를 작성하는 것입니다 (테이블 이름은 TSQL의 예약어이므로 대괄호로 묶어야합니다.)

INSERT INTO [Order] (CustomerId, Description, Cost) 
SELECT c.Id, f.Description, f.Cost 
FROM Flat_CSV_File f 
INNER JOIN Customer c ON f.Name = c.Name 
+0

니스! 나는 이것을 지금 시도 할 것이다. – Contango

4

위의 경우 @ 토마스는 완벽하게 실행 가능한 솔루션을 제공합니다. 그러나 때로는 사람들이 질문을하기 위해 단순화하기 때문에 많은 테이블로 이동해야하는 경우 (또는 첫 번째 테이블에 이름에 대한 고유 한 제약 조건이없는 경우) 수행하려는 작업을 설명합니다. 두.

먼저 스테이징 테이블에 데이터를 삽입하고 null이 될 id에 대한 열을 추가합니다. 그런 다음 OUTPUT 절을 사용하여 부모 테이블에 삽입하여 ID 및 자연 키를 테이블 변수에 출력합니다. 그런 다음 테이블 변수를 사용하여 준비 테이블의 ID 필드를 업데이트합니다.그런 다음 스테이징 테이블의 레코드를 다른 테이블에 삽입합니다. 이제는 거기에 ID가 있으므로 더 이상 본래의 부모 테이블에 액세스 할 필요가 없습니다. (레코드 수가 많으면 스테이징 테이블을 인덱싱 할 수도 있습니다.)

자연 키가없는 경우 어떤 레코드가 누가 누구인지를 식별 할 방법이 없으므로 프로세스가 더 어려워집니다. 그런 다음 보통 스테이징 테이블에 ID를 추가 한 다음 한 번에 하나의 레코드 (커서의 변수로 stagingtableid 포함)로 부모 테이블로 초기 가져 오기를 수행 한 다음 각 테이블 테이블 ID를 그대로 스테이징 테이블을 업데이트합니다 만들어진. 모든 초기 레코드가 업데이트되고 나면 세트 기반 프로세스를 사용하여 다른 테이블을 삽입하거나 업데이트합니다.

스테이징 테이블은 또한 프로덕션 테이블에 넣으려고 시도하기 전에 모든 잘못된 데이터를 로컬로 수정할 수있는 기회를 제공합니다.

복잡한 내용이거나 반복되는 프로세스 인 경우 다른 구문을 사용하면 MERGE 문법을 알아야 할 수 있습니다. 새 레코드 인 경우 삽입하고 기존 레코드 인 경우 업데이트합니다.

매우 복잡한 변환 인 경우 SSIS 사용을 고려할 수 있습니다.

+0

SSIS = SQL Server Integration Services – Contango

+0

의견을 보내 주셔서 감사 드리며, 이로 인해 강력한 시스템 디자인을 만드는 데 도움이됩니다. – Contango

+0

내가 어디를 보든 SSIS를 찾을 수없는 이유가 궁금했습니다. SSIS는 Visual Studio 2010의 일부가 아니기 때문에 Visual Studio 2010을 설치해야했습니다. – Contango

관련 문제