SQL Pivot或其他多字段值解决方案,用于从子表值返回单个对象

SQL Pivot或其他多字段值解决方案,用于从子表值返回单个对象,sql,tsql,Sql,Tsql,首先;只是为了让它的方式:)我已经给了一些表与工作,他们是不变的 主表称为Content,其中一行=1个内容。所有添加到其中的第一级动态字段(通过其自身表中的动态构建内容类型)都位于名为FieldValues的子表中,该子表具有多个特定值类型的字段,具体取决于字段本身:FieldStringValue、FieldDecimalValue、FieldLongValue、FieldDateValue、FieldBoolValue。标识映射通过ReferenceName字段进行处理,该字段是在构建内容

首先;只是为了让它的方式:)我已经给了一些表与工作,他们是不变的

主表称为Content,其中一行=1个内容。所有添加到其中的第一级动态字段(通过其自身表中的动态构建内容类型)都位于名为FieldValues的子表中,该子表具有多个特定值类型的字段,具体取决于字段本身:FieldStringValue、FieldDecimalValue、FieldLongValue、FieldDateValue、FieldBoolValue。标识映射通过ReferenceName字段进行处理,该字段是在构建内容类型本身时添加的唯一名称

我们希望返回一个单行内容“object”,其中子表行作为具有各自值的字段

到目前为止,我有一个SQL,它只对字符串值执行我想要的操作:

SELECT C.Id,C.ContentTypeId , Fields.*
FROM Contents AS C
OUTER APPLY (
    SELECT * FROM (
        SELECT ReferenceName,FieldStringValue
        FROM FieldValues
        WHERE ReferenceName IN (
            'recipename','recipenamehtml','url','introblurb','linkcopy','serves','makes','prep','cook','imgsetland','imgsetport'
        )
        AND ContentId = C.Id
    ) AS FieldList
    PIVOT (
        MAX(FieldStringValue)
        FOR ReferenceName IN (
            recipename, recipenamehtml, url, introblurb, linkcopy, serves, makes, prep, cook, imgsetland, imgsetport
        )
    ) AS PIV
) AS Fields
WHERE C.Id = 930 AND C.ContentTypeId = 2
但我有点困惑于如何“添加”检查FieldDecimalValue,例如,我是不是走错了路?例如,我如何在引用名称为“能量、卡路里、碳水化合物、蛋白质、膳食纤维、脂肪、脂肪、糖分”的字段中添加FieldDecimalValue而不是FieldStringValue中的值

我希望将表扫描保持在单个过程中,这就是为什么我尝试通过在单个查询上使用透视来进行此操作的原因-至少在我看来执行计划是正确的:)


编辑:服务器是SQL Server 2012,任何特定于t-SQL的技巧都可以。此外,我意识到我可以用FieldDecimalValue重复外部应用部分,但执行计划显示了2次表扫描以获取数据,这是我想要找到的解决方法(如果可能)

这似乎可行-不敢相信我以前没有想到:)

唯一的“问题”是,除非我再次手动转换,否则所有结果字段都将作为一种数据类型返回。但它似乎只导致一次表扫描

如果有人有更好的建议,他们仍然愿意接受

SELECT C.Id,C.ContentTypeId , Fields.*
FROM Contents AS C
OUTER APPLY (
    SELECT * FROM (
        SELECT ReferenceName,CASE
                WHEN ReferenceName IN ('energy', 'calories', 'carbs', 'protein', 'dietryfibre', 'fat', 'satfat', 'sugar') THEN CAST(FieldDecimalValue AS nvarchar(MAX))
                ELSE FieldStringValue
            END AS FSV
        FROM FieldValues
        WHERE ReferenceName IN (
            'recipename','recipenamehtml','url','introblurb','linkcopy','serves','makes','prep','cook','imgsetland','imgsetport'
            , 'energy', 'calories', 'carbs', 'protein', 'dietryfibre', 'fat', 'satfat', 'sugar'
        )
        AND ContentId = C.Id
    ) AS FieldList
    PIVOT (
        MAX(FSV)
        FOR ReferenceName IN (
            recipename, recipenamehtml, url, introblurb, linkcopy, serves, makes, prep, cook, imgsetland, imgsetport
            , energy, calories, carbs, protein, dietryfibre, fat, satfat, sugar
        )
    ) AS PIV
) AS Fields
WHERE C.Id = 930 AND C.ContentTypeId = 2