我正在尋找一種方法來基於來自另一個SQL查詢的條件在表中轉換數據。動態「列」在選擇與轉換
我的表格如下;
DataTable: Id | EntityId |值1 |值2 |值3 ... Value200
實體: Id |名稱
Fields: Id | EntityId | DataType | FieldNum
查找: Id | EntityId | FieldId
我的理想的輸出如下所示:
- Data.Id [ID]
- Field.Id [FieldId]
- Entity.Id [ENTITYID]
- [StringVal]
- [IntVal]
「StringVal」和「IntVal」都將基於「DataType」co設置如果設置爲「查找」(在「數據」表中存儲爲字符串),則應在此選擇查詢中將其解析爲整數,並填充到「IntVal」列中,否則,它應該直接解析到[StringVal]列。
我有下面的SQL查詢,它的工作原理是,但是,如果我有200個數據字段,我不得不復制每個字符串和查找的CASE和WHEN子句200次,然後有添加諸如「DateTime」之類的新類型的複雜性,這將導致進一步的問題。
SELECT
dt.Id as [Id],
f.Id as [FieldId],
f.EntityId as [EntityId],
CASE
WHEN f.DataType = 'string' and f.FieldNum = 0 THEN dt.Value0
WHEN f.DataType = 'string' and f.FieldNum = 1 THEN dt.Value1
WHEN f.DataType = 'string' and f.FieldNum = 2 THEN dt.Value2
WHEN f.DataType = 'string' and f.FieldNum = 3 THEN dt.Value3
WHEN f.DataType = 'string' and f.FieldNum = 4 THEN dt.Value4
WHEN f.DataType = 'string' and f.FieldNum = 5 THEN dt.Value5
WHEN f.DataType = 'string' and f.FieldNum = 6 THEN dt.Value6
WHEN f.DataType = 'string' and f.FieldNum = 7 THEN dt.Value7
WHEN f.DataType = 'string' and f.FieldNum = 8 THEN dt.Value8
WHEN f.DataType = 'string' and f.FieldNum = 9 THEN dt.Value9
ELSE NULL
END as [StringVal],
CAST(CASE
WHEN f.DataType = 'lookup' and f.FieldNum = 0 THEN dt.Value0
WHEN f.DataType = 'lookup' and f.FieldNum = 1 THEN dt.Value1
WHEN f.DataType = 'lookup' and f.FieldNum = 2 THEN dt.Value2
WHEN f.DataType = 'lookup' and f.FieldNum = 3 THEN dt.Value3
WHEN f.DataType = 'lookup' and f.FieldNum = 4 THEN dt.Value4
WHEN f.DataType = 'lookup' and f.FieldNum = 5 THEN dt.Value5
WHEN f.DataType = 'lookup' and f.FieldNum = 6 THEN dt.Value6
WHEN f.DataType = 'lookup' and f.FieldNum = 7 THEN dt.Value7
WHEN f.DataType = 'lookup' and f.FieldNum = 8 THEN dt.Value8
WHEN f.DataType = 'lookup' and f.FieldNum = 9 THEN dt.Value9
ELSE NULL
END as INT) as [IntVal]
FROM Lookups as i
left JOIN Fields f on i.FieldId = f.id and i.EntityId = f.EntityId
INNER join DataTable dt on i.EntityId = dt.EntityId
是否有更簡單的方法來實現這個目標?我需要保持這種索引視圖內,因此不能使用存儲過程,函數等
編輯:
試圖通過如在下面的評論指出函數來實現這一點,但是發現了同樣的問題。以下是我嘗試的功能解決方案。
SELECT
dt.Id as [Id],
f.Id as [FieldId],
f.EntityId as [EntityId],
CASE
WHEN f.DataType = 'string' THEN dbo.u_function_return_string
(
f.FieldNum, dt.Value0, dt.Value1,
dt.Value2, dt.Value3, dt.Value4,
dt.Value5, dt.Value6, dt.Value7,
dt.Value8, dt.Value9
)
ELSE NULL
END as [StringVal],
CAST(CASE
WHEN f.DataType = 'lookup' THEN dbo.u_function_returns_string
(
f.FieldNum, dt.Value0, dt.Value1,
dt.Value2, dt.Value3, dt.Value4,
dt.Value5, dt.Value6, dt.Value7,
dt.Value8, dt.Value9
)
ELSE NULL
END as INT) as [IntVal]
FROM dbo.Lookups as i
INNER JOIN dbo.Fields f on i.FieldId = f.id and i.EntityId = f.EntityId
INNER join dbo.DataTable dt on i.EntityId = dt.EntityId
功能:
CREATE FUNCTION u_function_return_string(
@fieldNum INT,
@val0 NVARCHAR(255),
@val1 NVARCHAR(255),
@val2 NVARCHAR(255),
@val3 NVARCHAR(255),
@val4 NVARCHAR(255),
@val5 NVARCHAR(255),
@val6 NVARCHAR(255),
@val7 NVARCHAR(255),
@val8 NVARCHAR(255),
@val9 NVARCHAR(255)
)
RETURNS NVARCHAR(255) WITH SCHEMABINDING
AS BEGIN
RETURN
CASE
WHEN @fieldNum = 0 THEN @val0
WHEN @fieldNum = 1 THEN @val1
WHEN @fieldNum = 2 THEN @val2
WHEN @fieldNum = 3 THEN @val3
WHEN @fieldNum = 4 THEN @val4
WHEN @fieldNum = 5 THEN @val5
WHEN @fieldNum = 6 THEN @val6
WHEN @fieldNum = 7 THEN @val7
WHEN @fieldNum = 8 THEN @val8
WHEN @fieldNum = 9 THEN @val9
END
END
GO
有什麼辦法嵌入一個 「行」 到一個函數?理想情況下,我想提交2個參數,即字段號和「dt」結果集。
編輯2:
找到一種方法,使一個功能拍攝一類...這作品...但不能從查詢找出如何解析成「DT *。」鍵入並傳遞給函數。
CREATE OR ALTER FUNCTION u_function_return_string(
@fieldNum INT,
@data dbo.DataTableType READONLY
)
RETURNS NVARCHAR(255) WITH SCHEMABINDING
AS BEGIN
DECLARE @tmp NVARCHAR(255)
DECLARE @value NVARCHAR(255)
set @tmp = 'Value' + CAST(@fieldNum as NVARCHAR(50))
SET @value = (SELECT @tmp FROM @data)
RETURN @value
END
GO
歡迎來到EAV的世界。 – lad2025
對於玩玩方式:[實體屬性值] http://sqlblog.com/blogs/aaron_bertrand/archive/2009/11/19/what-is-so-bad-about-eav-anyway.aspx – xQbert
看起來像一個類似的方法來實現最終目標,但是並不能幫助我解決我的問題:( –