2012-03-14 22 views
1

考慮以下表:是否可以創建多對多重繞的可編輯視圖?

產品

ID | Name | etc 
1 | Pen | wtv 
2 | Pad | wtv 
3 | Ball | wtv 
...| ... | ... 
thousands of products 

分類

ID | Name | etc 
1 | Office | wtv 
2 | Home | wtv 
3 | Park | wtv 
...| ... | ... 
hundreds of categories 

productCategoryMatrix

ProductID | CategoryID 
1   | 1 
1   | 2 
2   | 1 
2   | 2 
2   | 3 
3   | 3 
... et cetera 

該矩陣允許將多個類別分配給單個產品(典型的多對多關聯)。例如,屬於兩類,Office首頁。我想創建這個數據的可編輯視圖這將是這樣的:

ProductsWithCategories

ProductID | ProductName | Category | Category | Category | Category | Category 
1   | Pen   | 1  | 2  |   |   | 
2   | Pad   | 1  | 2  | 3  |   | 
3   | Ball  | 3  |   |   |   | 
      |    ... Thousands of products ...    | 

注意,如果將產品指定小於5個大類,最後一欄可以保持爲空, 就像在此樣品中。另請注意,業務邏輯規定,單個產品永遠不會超過5個類別,因此只需要5列。

是否可以使用SQL Server 2008 R2創建這種視圖? 如果您的解決方案也適用於SQL Server 2000,那將是非常棒的,因爲我們只在三週內升級到2008年。如果不是,我們將等待:)

回答

2

任何視圖都可以使用INSTEAD OF觸發器進行更新。

http://msdn.microsoft.com/en-us/library/ms187956.aspx

在你的情況下,有沒有辦法讓SQL Server自動使它可更新,但你可以在你的觸發映射到行列。

看一看這些頁面:

http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=120679

SQL pivoted table is read-only and cells can't be edited?

視圖可以從這個進行:

DECLARE @Products TABLE (ID INT, Name VARCHAR(50)); 
DECLARE @Categories AS TABLE (ID INT, Name VARCHAR(50)); 
DECLARE @ProductCategoryMatrix AS TABLE (ProductID INT, CategoryID INT); 

INSERT INTO @Products (ID, Name) VALUES (1, 'Pen'), (2, 'Pad'), (3, 'Ball'); 
INSERT INTO @Categories VALUES (1, 'Office'), (2, 'Home'), (3, 'Work'); 
INSERT INTO @ProductCategoryMatrix VALUES (1, 1), (1, 2), (2, 1), (2, 2), (2, 3), (3, 3); 

-- CREATE VIEW AS -- (change variables to real tables) 
WITH CategoriesOrdered AS (
    SELECT p.ID AS ProductID 
      ,'Cat' + CAST(ROW_NUMBER() OVER(PARTITION BY pc.ProductID ORDER BY pc.CategoryID) AS VARCHAR(1)) AS CategoryColumn 
      ,pc.CategoryID 
    FROM @Products p 
    INNER JOIN @ProductCategoryMatrix pc 
     ON pc.ProductID = p.ID 
) 
,CategoriesFlat AS (
    SELECT * 
    FROM CategoriesOrdered 
    PIVOT (MIN(CategoryID) FOR CategoryColumn IN ([Cat1], [Cat2], [Cat3], [Cat4], [Cat5])) AS pvt 
) 
,ProductsWithCategories AS (
    SELECT * 
    FROM @Products p 
    LEFT JOIN CategoriesFlat cf 
     ON cf.ProductID = p.ID 
) 
SELECT * 
FROM ProductsWithCategories; 

這個製作觸發器會涉及相當多的的代碼,但不是非常困難。

+0

可不可以給這種過程的一個簡單的例子? – Shawn 2012-03-14 22:46:02

+0

@Shawn看到我給的兩個鏈接。 – 2012-03-15 14:33:51

+0

感謝您的鏈接。不幸的是,他們沒有完成我想要做的事情。他們的方法爲每個類別創建了一個新的專欄(其中有數百個專欄),與Indikaf的解決方案類似。我只需要5列,其中將出現類別ID ...我的問題中的ProductsWithCategories表說明了我試圖實現的目標。 – Shawn 2012-03-15 16:59:29

0

這工作完全在SQL 2K,我已經測試

select 
p.ID, 
p.Name, 
c1.cid  as cat1, 
c2.cid  as cat2, 
c3.cid  as cat3, 
c4.cid  as cat4, 
c5.cid  as cat5 
from 
Products p 
inner join     -- use left join if you want to have listed products with any category 
    (select pcm1.ProductID, min(pcm1.CategoryID) as cid 
    from productCategoryMatrix pcm1 group by ProductID) as c1 on p.ID = c1.productID 

left join 
    (select pcm1.productID, min(pcm2.CategoryID) as cid 
    from  productCategoryMatrix pcm1 
    left join productCategoryMatrix pcm2 on pcm1.productID = pcm2.productID and pcm1.CategoryID < pcm2.CategoryID 
    group by pcm1.ProductID 
    ) as c2 on p.ID = c2.productID 

left join 
    (select pcm1.productID, min(pcm3.CategoryID) as cid 
    from  productCategoryMatrix pcm1 
    left join productCategoryMatrix pcm2 on pcm1.productID = pcm2.productID and pcm1.CategoryID < pcm2.CategoryID 
    left join productCategoryMatrix pcm3 on pcm1.productID = pcm3.productID and pcm2.CategoryID < pcm3.CategoryID 
    group by pcm1.ProductID 
    ) as c3 on p.ID = c3.productID 

left join 
    (select pcm1.productID, min(pcm4.CategoryID) as cid 
    from  productCategoryMatrix pcm1 
    left join productCategoryMatrix pcm2 on pcm1.productID = pcm2.productID and pcm1.CategoryID < pcm2.CategoryID 
    left join productCategoryMatrix pcm3 on pcm1.productID = pcm3.productID and pcm2.CategoryID < pcm3.CategoryID 
    left join productCategoryMatrix pcm4 on pcm1.productID = pcm4.productID and pcm3.CategoryID < pcm4.CategoryID 
    group by pcm1.ProductID 
    ) as c4 on p.ID = c4.productID 

left join 
    (select pcm1.productID, min(pcm5.CategoryID) as cid 
    from  productCategoryMatrix pcm1 
    left join productCategoryMatrix pcm2 on pcm1.productID = pcm2.productID and pcm1.CategoryID < pcm2.CategoryID 
    left join productCategoryMatrix pcm3 on pcm1.productID = pcm3.productID and pcm2.CategoryID < pcm3.CategoryID 
    left join productCategoryMatrix pcm4 on pcm1.productID = pcm4.productID and pcm3.CategoryID < pcm4.CategoryID 
    left join productCategoryMatrix pcm5 on pcm1.productID = pcm5.productID and pcm4.CategoryID < pcm5.CategoryID 
    group by pcm1.ProductID 
    ) as c5 on p.ID = c5.productID 
+1

@Shawn這個解決方案,你測試過嗎?這不是你想要的嗎? – 2012-03-19 12:44:38

相關問題