我正在寻找一种基于来自另一个SQL查询的条件在表中转换数据的方法。
我的表格如下;
数据表: Id | EntityId | Value1 | Value2 |价值3 ......价值200
实体: Id |名称
字段: Id | EntityId | DataType | FieldNum
查找 Id | EntityId | FieldId
我的理想输出如下:
“StringVal”和“IntVal”都将根据“Fields”表中的“DataType”列设置,如果设置为“lookup”(在“Data”表中以字符串形式存储),它应该在此选择查询中解析为整数并填充在“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
答案 0 :(得分:0)
您可以使用标量值的schemabinding函数和动态sql,并在select查询中使用一个case函数调用替换多个case语句。
我修改了您的查询以解释该方法。请根据您的要求进行更改。
<?php
$cart = array(
'547650d3bfb9bce7ea6d61faf312fa41' => array
(
'id' => 1502369193000,
'productid' => 'Product 1',
'qty' => 1,
'type' => 'sales',
'user_id' => 'admin',
'rowid' => '547650d3bfb9bce7ea6d61faf312fa41'
),
'7473a2e4d2e4150c7de11d201538e179' => array
(
'id' => 1502369241000,
'productid' => 'SG KENNA',
'qty' => 1,
'type' => 'purchase',
'user_id' => 'admin',
'rowid' => '7473a2e4d2e4150c7de11d201538e179'
)
);
$found = false;
foreach ($cart as $key => $data) {
if ($data['user_id'] == 'admin' && $data['type'] == 'sales') {
$found = true;
}
}
if ($found === false) {
echo 'not found';
} else {
echo 'found';
}
Output is : Found