2013-03-02 122 views
1

動態屬性我設計了一個小數據庫的想法是,我有一個表的產品和每個產品都有其類別和屬性的動態列表(這些屬性在另一個表):如何處理選擇從數據庫

ProductCategories{ProductCategoryId, Name} 
Products{ProductId, Name, ProductCategoryId} 

我在這裏綁定某個類別的產品。現在,每一個產品分類是另一桌在那裏我可以爲該類別添加屬性:每個屬性

CategoryProperties{CategoryPropertyId, ProductCategoryId, Name} 

值是在此表:

ProductPropertyValues{ProductId, CategoryPropertyId, Value} 

問題是,當我執行查詢:

select p.Name as ProductName, m.Name as Manufacturer, pc.Name as Category 
from products p 
left join dbo.Manufacturers m 
on p.ManufactureId = m.ManufactureId 
left join dbo.ProductCategories pc 
on p.ProductCategoryId = pc.ProductCategoryId 

這給我造成這樣的:

| some product name | RedBull | Can | 

但我想獲得和所有相關屬性爲此產品類別這就是問題所在。當我嘗試此查詢:

select p.Name as ProductName, m.Name as Manufacturer, pc.Name as Category, cp.Name, ppv.Value 
from products p 
left join dbo.Manufacturers m 
on p.ManufactureId = m.ManufactureId 
left join dbo.ProductCategories pc 
on p.ProductCategoryId = pc.ProductCategoryId 

left join dbo.CategoryProperties cp 
on pc.ProductCategoryId = cp.ProductCategoryId 

left join dbo.ProductPropertyValues ppv 
on p.ProductId = ppv.ProductId 

此查詢,而不是一行的結果後,我得到「121」結果。 我不知道我在做什麼錯。 我想要得到的結果,如:

| Product name  | Manufacturer | Category | prop1 | prop2  | prop3| Prop4   |  
| some product name | RedBull  | Can  | 34 | something | 45.6 | something else | 

什麼我做錯了或這是不可能的?
我在這裏得到了一些交叉連接,據我瞭解。 enter image description here

enter image description here enter image description here

回答

2

這聽起來像你試圖PIVOT的數據。這會將您的行值轉換爲列。

如果您有屬性轉換的一組號碼,然後你可以硬編碼的查詢到與此類似:

select * 
from 
(
    select p.Name as ProductName, 
    m.Name as Manufacturer, 
    pc.Name as Category, 
    cp.Name, 
    ppv.Value 
    from products p 
    left join dbo.Manufacturers m 
    on p.ManufactureId = m.ManufactureId 
    left join dbo.ProductCategories pc 
    on p.ProductCategoryId = pc.ProductCategoryId 
    left join dbo.CategoryProperties cp 
    on pc.ProductCategoryId = cp.ProductCategoryId 
    left join dbo.ProductPropertyValues ppv 
    on p.ProductId = ppv.ProductId 
    and cp.CategoryPropertyId = ppv.CategoryPropertyId 
) src 
pivot 
(
    max(value) 
    for Name in ([Code], [Data], etc) 
) piv 

它變得有點困難,如果你有數目不詳的值。你將不得不使用動態sql來執行此操作。我向您展示了一個靜態版本,因爲從硬編碼版本轉移到動態解決方案更容易。

動態版本的關鍵是獲取列名稱。完整的腳本將與此類似:

DECLARE @cols AS NVARCHAR(MAX), 
    @query AS NVARCHAR(MAX) 

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(name) 
        from dbo.CategoryProperties 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

set @query = 'SELECT ProductName, Manufacturer, Category,' + @cols + ' from 
      (
       select p.Name as ProductName, 
        m.Name as Manufacturer, 
        pc.Name as Category, 
        cp.Name, 
        ppv.Value 
       from products p 
       left join dbo.Manufacturers m 
        on p.ManufactureId = m.ManufactureId 
       left join dbo.ProductCategories pc 
        on p.ProductCategoryId = pc.ProductCategoryId 
       left join dbo.CategoryProperties cp 
        on pc.ProductCategoryId = cp.ProductCategoryId 
       left join dbo.ProductPropertyValues ppv 
        on p.ProductId = ppv.ProductId 
        and cp.CategoryPropertyId = ppv.CategoryPropertyId 
      ) x 
      pivot 
      (
       max(value) 
       for Name in (' + @cols + ') 
      ) p ' 

execute(@query) 
+0

這是否意味着每個屬性名稱必須有'Prop_'前綴? – 1110 2013-03-02 15:41:53

+0

@ 1110不,我正在創建名稱爲'Prop_'的列,然後在每個列的後面添加行號值,因此如果您有5個屬性,那麼您將有名爲'Prop_1','Prop_2'等的列我用表結構創建了一個[sql小提琴](http://www.sqlfiddle.com/#!3/f5df4),你可以添加一些插入語句對於一些示例數據然後在評論中發佈新創建的模式鏈接?用數據顯示這一點會更容易。 – Taryn 2013-03-02 15:45:06

+0

在動態查詢中,我得到'關鍵字附近的語法不正確'。':'fot this line')t on p.ProductId' – 1110 2013-03-02 15:50:01

1

要解答有關問題的交叉聯接,我認爲這個問題是你是不是綁ProductPropertyValuesCategoryProperties。因此,對於每個CategoryProperties行,您將獲得ProductPropertyValues所有類別的所有屬性。

現在,就獲取所需的格式而言,這就是所謂的「pivoted」,因爲您想要獲取垂直列表(所有屬性)和「透視」,並將其水平渲染。這很難動態執行,因爲儘管SQL Server確實有一個PIVOT命令,但它要求您知道在編碼時用於列名的所有值。雖然如果你知道你的房產被稱爲「道具1」,「道具2」等,那麼這將起作用,但我認爲這些名稱因產品而異。

如何確定您是否在一行中獲取所有屬性?它可以完成,但會變得很複雜。

+0

你是對的交叉連接。我現在改變了查詢,它返回了11行。這就是我擁有的那個類別的多少屬性。這部分是固定的,但我真的需要在一行。我一整天都在苦苦掙扎:( – 1110 2013-03-02 15:26:53

+0

@ 1110你有最多的房產要展示嗎?或者只是「無論有多少」? – 2013-03-02 15:35:34

+0

所有屬性。所以第二個。 – 1110 2013-03-02 15:37:07