首先;只是为了让它不受影响:)我已经获得了一些工作表,它们是不可更改的。
主表名为Content,单行= 1条内容。添加到它的所有第一级动态字段(通过其自己的表中的动态构建的内容类型)位于名为FieldValues的子表中,该子表具有针对特定值类型的多个字段,具体取决于字段本身:FieldStringValue,FieldDecimalValue,FieldLongValue,FieldDateValue, FieldBoolValue。标识映射通过ReferenceName字段处理,该字段是在构建内容类型本身时添加的唯一名称。
想要的是返回单行内容'对象',子表行作为具有各自值的字段。
到目前为止,我有这个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的值添加参考名称为“energy,calories,carbs,protein,dietryfibre,fat,satfat,sugar”的字段?
我想将表扫描保持一次通过,这就是为什么我试图通过在单个查询上使用数据透视来实现这一点 - 至少执行计划对我来说没问题:)
编辑:服务器是SQL Server 2012,任何特定于t-sql的技巧都可以。另外我意识到我可以用FieldDecimalValue重复OUTER APPLY部分,但是执行计划显示2个表扫描以获取数据,这是id想找到解决办法(如果可能的话)
答案 0 :(得分:1)
这似乎有用 - 不敢相信我之前没有想到它:)。
只有'问题'是所有结果字段都将作为一种数据类型返回,除非我再次手动转换回来。但它似乎导致单个表扫描。
如果有人有这些建议,仍然可以提供更好的查询建议。
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