2011-02-11 25 views
5

我想將現有的表格轉換爲第一範式(可能的最簡單的標準化;請參閱示例)。什麼是T-SQL規範化現有的表?

你碰巧知道什麼是T-SQL是這樣的問題?非常感謝!

enter image description here

更新

嘗試下面的答案,它的工作完美。以下是我用來測試答案的步驟:

  1. 啓動Microsoft SQL Management Studio。
  2. 用下面的數據創建表格。
  3. 確保「客戶」中的ID設置爲「主鍵」和「身份」。
  4. 確保「訂單」中的ID沒有特殊設置(其外鍵)。
  5. 打開數據庫圖表,然後在「客戶」和「訂單」表之間創建1:*關係。
  6. 在「客戶」表格和「訂單」表格上執行腳本,它會自動正確地爲您正常化數據。
  7. 如果您從剛剛導入的平面.csv文件開始,並且希望將信息複製到數據庫中的規範化表單,這非常有用。
+0

您的圖片鏈接無法正常工作。 – 2011-02-11 17:46:19

+0

我同意這是一個合理的重構,但它不是標準化。沒有什麼功能上依賴於`name`。 – 2011-02-11 17:52:28

+0

我承認這是一個玩具的例子來問這個問題 - 與此相比,完整的問題有點複雜。 – Contango 2011-02-11 18:03:47

回答

4

與客戶表

INSERT INTO Customer (Name) 
SELECT DISTINCT Name 
FROM Flat_CSV_File 

開始如果您有反覆進口

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 

訂單(您的表名稱Order是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

如果這是一次性過程,我會先操作.csv,然後在那裏形成包含主鍵的表。當您填充SQL數據庫,使用

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 

如果你需要一個純粹的TSQL的解決方案,我將創建臨時表做同樣的基本的東西,並從臨時表,而不是插入的.csv。

+0

沒有理由做一個你打開和關閉身份插入的過程。這不是一個好習慣。 – HLGEM 2011-02-11 17:56:41

4

最簡單的解決方法就是編寫一個查詢做進口:

-- 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

不錯!我現在就試試這個。 – Contango 2011-02-11 17:57:10

4

在上述情況下,@Thomas有一個完美可行的解決方案。然而,有時候人們爲了提出問題而簡化,所以我會解釋如果您需要去多個表(或者第一個表沒有唯一的名稱限制),您可能會想要做什麼,而不僅僅是二。

首先,我會將數據插入登臺表並添加一個id爲空的列。然後,我會使用OUTPUT子句向父表寫入插入操作,以將ID和自然鍵輸出到表變量。然後,我會使用表變量來更新登臺表中的id字段。然後我會將登臺表中的記錄插入到其他表中。因爲我現在有了id,所以不再需要訪問原始父表。 (如果記錄的數量很大,我也可以爲登臺表編制索引)。

現在,如果您沒有自然鍵,則該過程變得更加困難,因爲您無法確定哪條記錄會發送給誰。然後,我通常爲登臺表添加一個身份,然後一次向父表進行一次初始導入(包括作爲遊標中的變量的stagingtableid),然後使用每個父表id儘快更新登臺表創建。一旦所有的初始記錄被更新,我使用基於集合的過程插入或更新到其他表。

臨時表還可以讓您在試圖將其放入生產表之前修復任何不良數據的機會。

如果事情很複雜或者這是一個重複的過程,您可能需要知道的其他語法是MERGE語句。如果它是新記錄,則會插入,如果它是現有記錄,則進行更新。

如果這是一個非常複雜的轉換,您可以考慮使用SSIS。