2017-06-03 70 views
0

我有以下架構。在這Ho要編寫選擇查詢EAV - 實體屬性值模型

  • Types代表數據庫表
  • TypeProperty代表表第
  • TypeRow代表表中的行

我想寫一個SELECT查詢,我將通過單Type,它應該給我所有的TypeProperty,TypeRowTypeValue這些與這些屬性

我將展示在web應用中這個數據,其中用戶將選擇類型從下拉菜單和應用程序將獲得屬性和相關並顯示它們作爲一個完整的網格。

我使用SQL Server 2014

誰能幫助我嗎?

enter image description here

+1

順便說一句,EAV是一個壞模式的原因之一是,它很難得到表結構是正確的,以最大化(糟糕的)性能。您應該對(TypeRowId,TypePropertyId)的TypeValue使用複合鍵,而不是具有單列人造鍵。 –

+1

EAV不是邪惡的。我知道我們都有教條,但在我看來,它只是您工具帶中的另一種選擇。在適當的情況下,它可能是一個有價值的有效解決方案。 –

回答

2

所以,我要去嘗試,並採取裂縫在你一直在幫助您使用什麼卡納安加盟。 這聽起來像你有兩個不同的查詢到數據庫: 1)查詢結果的'類型(S)'列表爲您的下拉列表中,(你應該能夠很容易地做到這一點) 2)查詢結果的下拉菜單中的「屬性」,「行」和「值」列表中,將屬性設置爲表格的表頭。

對我來說,處理這個問題的最簡單和最好的方法是使用Kannan的腳本(可能在存儲過程中,也許是一個視圖?)獲取數據,並從您的後端代碼中創建網格應用程序或前端客戶端。但是,如果你不能,這是一個應該起作用的腳本,或者至少讓你開始。

我會建議可能創建兩個存儲過程,一個檢索數據,另一個使用動態sql進行數據透視。

CREATE PROCEDURE dbo.EAV_GridGenerator 
    @TypeId int = 0, 
    @param2 int 
AS 
BEGIN TRY 
DECLARE @cols varchar(max), 
     @query varchar(max); 
     --TODO: CLEAN UP VARIABLE NAMES THROUGHOUT 
SELECT trow.TypesId, tprop.PropertyName AS [Column], trow.TypeRowId AS [RowID], tval.Value AS [Data] 
INTO #TT2 
FROM dbo.[Types] AS t 
    JOIN dbo.TypeRow trow 
     ON t.typesId = trow.typesId 
     JOIN dbo.TypeValue tval 
      ON tval.TypeRowsId = trow.TypeRowId 
      JOIN dbo.[TypeProperty] tprop 
       ON tval.TypesPropertyId = tprop.TypePropertyId 
WHERE trow.TypesId = @TypeId 
    --AND t.IsActive = 1 AND tprop.IsActive = 1 AND trow.IsActive = 1 AND tval.IsActive = 1--TODO: IDK but you should probably add both of these 
--  AND t.IsDelete = 1 AND tprop.IsDelete = 1 AND trow.IsDelete = 1 AND tval.IsDelete = 1--TODO: IDK but you should probably add both of these 
ORDER BY RowID, [Column], Data 


SELECT @cols = STUFF((SELECT DISTINCT TOP 100 PERCENT 
           '],[' + t.[Column] 
         FROM #TT2 AS t 
         --ORDER BY '],[' + t.ID 
         FOR XML PATH('') 
        ), 1, 2, '') + ']' 

SET @query = N'SELECT RowID,'+ @cols +' FROM 
(SELECT tt2.RowID,tt2.[Column] , tt2.Data FROM #tt2 AS tt2) p 
PIVOT (max([data]) FOR [Column] IN ('+ @cols +')) 
AS pvt;' 

EXECUTE(@query) 

drop table #TT2 

END TRY 
BEGIN CATCH 
    --TODO: PROPER CATCH 
END CATCH 
+1

這就是我正在尋找的。謝謝!人。 –

2

一個簡單的加入將工作..你看這個?

Select * --your required columns 
    from Types t 
    inner join TypesProperty tp 
     on t.TypesId = tp.TypesId 
    inner join TypeRow tr 
     on t.TypesId = tr.TypesId 
    Left join TypeValue tv 
     on tp.TypesPropertyId = tv.TypesPrpertyId 

- 您需要使用typeRowid與typeValue如果您需要值的詳細信息

+1

感謝@Kannan的回覆。這是您提供查詢的結果。 https://www.dropbox。com/s/t1eg8k3zzuh0as2/00001_EAV.png?dl = 0 但是我很難在Grid中顯示這些數據。這個查詢可以更精緻一點嗎?所以我得到像網格一樣的結構?我嘗試過'Piviot',但它沒有解決我的問題。 –

+0

您能否提供我所需的結果格式/預期輸出? –

+0

我想在我的Web應用程序中使用這種類型的網格。 https://www.dropbox.com/s/tp0l7te6xvw3981/00002_EAV.png?dl=0 用戶將選擇'T​​ypeName'從中可以是'Department'或'Employee'例如。一旦選擇了'TypeName',我的應用程序就會像我在屏幕截圖中顯示的那樣填充網格。 –