如何用SPARQL判断maximumTemperatureChange是否大于平均温差?
SPARQL查询:判断最大温度变化是否大于温差平均值
我在Protégé中用以下SPARQL查询能获取所有温差的平均值:
SELECT (AVG(?difference) AS ?averageDifference) WHERE { ?originalData a validation:OriginalData . ?originalData validation:hasCollection ?originalCollection . ?originalCollection a validation:TimeSeriesCollection ; validation:hasTemperature ?originalTemperature ; validation:hasTimeStamp ?originalTime . ?counterfactualData a validation:CounterfactualData . ?counterfactualData validation:hasMaximumTemperatureChange ?maximumTemperatureChange . ?counterfactualData validation:hasCollection ?counterfactualCollection . ?counterfactualCollection a validation:TimeSeriesCollection ; validation:hasTemperature ?counterfactualTemperature ; validation:hasTimeStamp ?originalTime . BIND(ABS(?counterfactualTemperature - ?originalTemperature) AS ?difference) }
但我需要得到一个布尔结果(true/false),用来判断maximumTemperatureChange是否大于这个温差平均值。我尝试了四种方法都没得到预期结果:
BIND(IF(?maximumTemperatureChange > (AVG(?difference)), true, false) AS ?result)BIND(IF(?maximumTemperatureChange > ?totalDifference), true, false) AS ?result)BIND(AVG(?difference) AS ?averageDifference)(结果错误)SELECT (IF(?maximumTemperatureChange > (AVG(?difference)), true, false) AS ?result)
可行实现方法
核心问题是聚合函数(如AVG)不能直接和非聚合变量在SELECT的判断逻辑里混用——AVG是对整个结果集计算的全局值,而?maximumTemperatureChange是单条数据的变量,必须先算出全局平均温差,再进行比较。
情况1:只有一个CounterfactualData实例(即唯一的maximumTemperatureChange值)
用子查询先计算出平均温差,再和目标值比较:
SELECT (IF(?maximumTemperatureChange > ?averageDifference, true, false) AS ?result) WHERE { # 子查询计算全局平均温差 { SELECT (AVG(?difference) AS ?averageDifference) WHERE { ?originalData a validation:OriginalData . ?originalData validation:hasCollection ?originalCollection . ?originalCollection a validation:TimeSeriesCollection ; validation:hasTemperature ?originalTemperature ; validation:hasTimeStamp ?originalTime . ?counterfactualData a validation:CounterfactualData . ?counterfactualData validation:hasCollection ?counterfactualCollection . ?counterfactualCollection a validation:TimeSeriesCollection ; validation:hasTemperature ?counterfactualTemperature ; validation:hasTimeStamp ?originalTime . BIND(ABS(?counterfactualTemperature - ?originalTemperature) AS ?difference) } } # 获取唯一的最大温度变化值 ?counterfactualData a validation:CounterfactualData ; validation:hasMaximumTemperatureChange ?maximumTemperatureChange . }
情况2:存在多个CounterfactualData实例
如果有多个最大温度变化值需要分别和全局平均温差比较,同样用子查询先算出平均值,再关联每个实例进行判断:
SELECT ?counterfactualData (IF(?maximumTemperatureChange > ?averageDifference, true, false) AS ?isGreaterThanAvg) WHERE { # 子查询计算全局平均温差 { SELECT (AVG(?diff) AS ?averageDifference) WHERE { ?originalData a validation:OriginalData . ?originalData validation:hasCollection ?originalCollection . ?originalCollection a validation:TimeSeriesCollection ; validation:hasTemperature ?originalTemp ; validation:hasTimeStamp ?time . ?cfData a validation:CounterfactualData . ?cfData validation:hasCollection ?cfCollection . ?cfCollection a validation:TimeSeriesCollection ; validation:hasTemperature ?cfTemp ; validation:hasTimeStamp ?time . BIND(ABS(?cfTemp - ?originalTemp) AS ?diff) } } # 遍历每个CounterfactualData实例,获取其最大温度变化值 ?counterfactualData a validation:CounterfactualData ; validation:hasMaximumTemperatureChange ?maximumTemperatureChange . }
之前方法失败的原因
- 方法1/4:直接在
IF中嵌套AVG,SPARQL不允许将聚合函数(全局计算)和非聚合变量(单行取值)直接混用在SELECT表达式中,逻辑上不匹配。 - 方法2:
?totalDifference未定义,属于语法错误。 - 方法3:
BIND是对每行数据做计算,而AVG是全局聚合函数,不能在BIND中直接使用聚合函数。
内容的提问来源于stack exchange,提问作者Ibrahim Aliyev
相关产品推荐
相关产品推荐

