2012-07-17 25 views
0

我有一個Excel電子表格中導入數據的平面表....SQL Server轉換平表的屬性基於結構

tbl_ProductsImport 
---------------------------------------------------------------------------------- 
ProductId | Name | Description | Attribute1 | Attribute2 | Attribute3 | Attribute4 etc... 
---------------------------------------------------------------------------------- 
12345  P1  Some desc.. x       x   x 
12346  P2  Some desc..    x    
12347  P3  Some desc.. x   x   x   x 
12348  P4  Some desc.. x          x 

我想將其轉換成下表結構...

tbl_Products 
------------------------------ 
ProductId (pk) | Name | Description 

tbl_Attributes 
---------------------------------------------- 
AttributeId (pk) | Name (derrived from column) 

tbl_ProductAttributes 
---------------------- 
ProductId (fk) | AttributeId (fk) 

所以我問,我該怎麼去寫一個聲明來做到這一點?

編輯:這將成爲執行前截斷所有現有數據的計劃數據導入作業的一部分。

+0

是否有_some_'默認'屬性集?什麼是屬性?特別是因爲它們看起來非常漂亮(除非你在'productAttributes'中留下了一些東西)?否則,您將前往一個EAV(實體 - 屬性 - 值)表,該表通常被視爲SQL反模式。除此之外,他們通常很難有效地進行查詢。另外,不要用'tbl_'前綴表 - 除此之外,如果您更改實際的模式,但將其重新創建爲「傳統」應用程序的視圖,則看起來很奇怪。 – 2012-07-17 15:47:01

+0

這些屬性的值並不重要,因爲當字段的值爲「x」時,我只需要將它們分配給特定的產品。爲什麼EAV通常包含SQL反模式?我還可以怎樣去做這件事,以便讓屬性從導入變爲導入,而不必每次都強制鍵入和重新設計我的消費應用程序? – 2012-07-17 16:10:11

+2

_How_值是否在進口之間變化(從Excel中推定)?根據發生的情況,最好通過更改基礎模式_anyways_來實現。或者,它可能表明還有其他問題(比如,有人意外地格式化了一列錯誤)。 EAV通常被認爲是反模式,因爲它們有時被實施爲真正應該是單行的東西(也就是說,所有屬性都是必需的)。大多數情況下,EAV必須進行調整才能被智能地查詢,並且會失去(本地)類型安全性(因爲所有內容均以字符串形式存儲)。 – 2012-07-17 16:25:54

回答

1

嗯。這會工作嗎?討厭的動態SQL,但有時它必須完成。

INSERT tbl_Products 
SELECT ProductId, Name, Description 
FROM tbl_ProductsImport 

INSERT tbl_Attributes (Name) 
SELECT c.name 
FROM sys.sysobjects o 
JOIN sys.syscolumns c ON o.id = c.id 
WHERE o.name = 'tbl_ProductsImport' 
AND  c.name LIKE 'Attribute%' 

DECLARE @DynamicSQL VARCHAR(MAX) 
SET  @DynamicSQL = '' 

DECLARE @AttributeId INT 
DECLARE @AttributeName NVARCHAR(255) 

SELECT @AttributeId = MIN(AttributeId) 
FROM tbl_Attributes 

WHILE (@AttributeId <= (SELECT MAX(AttributeId) FROM tbl_Attributes)) 
BEGIN 
    SELECT @AttributeName = Name 
    FROM dbo.tbl_Attributes 
    WHERE AttributeId = @AttributeId 

    SELECT @DynamicSQL = 
    'INSERT tbl_ProductAttributes 
    SELECT ProductId, ' + CONVERT(VARCHAR, @AttributeId) + ' 
    FROM tbl_ProductsImport 
    WHERE ' + @AttributeName + ' = 1' 

    EXEC (@DynamicSQL) 

    SET @AttributeId = @AttributeId + 1 
END 

這假定的值在tbl_ProductsImport屬性是比特。沒有嘗試過,所以可能是超級失敗。

Jim