有没有更好的方法来执行此查询

时间:2019-02-21 21:59:46

标签: sql-server sql-optimization

我有一个表,其中将Json数据保留在RelatedObject列下。表结构如下;

+------+------------+-----------------+----------------------+
| [Id] | [ActionId] | [RelatedObject] | [InitiatedTimeStamp] |
+------+------------+-----------------+----------------------+

我存储两种不同的Json对象。这样的事情;

{
    "firstName": "FName",
    "lastName": "LName",
    "emailAddress": "xxx@gmail.com",    
    "contactPref": {
        "lm_contclassne": "on",
        "lm_contclassneindustrial": "on",
        "lm_contclassneconstruction": "on"
     }
}

第二种是第一个的子集。像这样的东西

{
  "lm_contclassne": "on",
  "lm_contclassneindustrial": "on",
  "lm_contclassneconstruction": "on"
}

现在,问题在于为查询选择Json路径(在某些情况下,属性为lm_contclassne,在其他情况下,属性为contactPref.lm_contclassne)。这就是我的做法。

SELECT [Id],
  [ActionId],
  [InitiatedTimeStamp],
  JSON_VALUE(RelatedObject, IIF(JSON_QUERY(RelatedObject, '$.contactPref') IS NULL, '$.lm_contclassne', '$.contactPref.lm_contclassne')) lm_contclassne,
  JSON_VALUE(RelatedObject, IIF(JSON_QUERY(RelatedObject, '$.contactPref') IS NULL, '$.lm_contclassneindustrial', '$.contactPref.lm_contclassneindustrial')) lm_contclassneindustrial,
  JSON_VALUE(RelatedObject, IIF(JSON_QUERY(RelatedObject, '$.contactPref') IS NULL, '$.lm_contclassneconstruction', '$.contactPref.lm_contclassneconstruction')) lm_contclassneconstruction
FROM [SaveStatus]

工作正常。

我的问题是,无论如何我是否可以优化查询?您可以看到我对每个Json属性都设置了相同的条件。我可以检查一次IIF(JSON_QUERY(RelatedObject, '$.contactPref') IS NULL并将结果用于其余的选择吗?任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

您可以缩小到我想的程度(稍微简洁一点):

SELECT [Id],
       [ActionId],
       [InitiatedTimeStamp],
       JSON_VALUE(RelatedObject, IIF(RO.cP IS NULL, '$.lm_contclassne', '$.contactPref.lm_contclassne')) lm_contclassne,
       JSON_VALUE(RelatedObject, IIF(RO.cP IS NULL, '$.lm_contclassneindustrial', '$.contactPref.lm_contclassneindustrial')) lm_contclassneindustrial,
       JSON_VALUE(RelatedObject, IIF(RO.cP IS NULL, '$.lm_contclassneconstruction', '$.contactPref.lm_contclassneconstruction')) lm_contclassneconstruction
FROM [SaveStatus] SS
     CROSS APPLY(VALUES(JSON_QUERY(RelatedObject, '$.contactPref'))) RO(cP);