获取两个日期之间的所有月份的SPARQL查询

5

我正在使用TopBraid Composer工具开发一个SPARQL查询,以获取每个月中数据质量规则的数量。

我已经有了开始时间和结束时间,但我需要获取开始时间和结束时间之间所有的月份,这样我才能计算该时间段内适用于数据质量规则的总数。

我的当前查询和结果如下:

SELECT *    
WHERE    
{    
   ?Rules CDE:Data_Quality_Rule_added_on ?Date1.    
   ?Rules CDE:Data_Quality_Removed_On ?Date2

   BIND(month(?Date1) AS ?Month1)    
   BIND(month(?Date2) AS ?Month2)    
   BIND(smf:duration("mon",?Date1,?Date2) AS ?dur)    
}    
LIMIT 5

| [Rules]                  | Date1      | Date2      | Month1 | Month2 | dur    
| CDE:Data_Quality_Rule_13 | 2016-01-28 | 2016-09-15 | 01     | 09     | 8   
| CDE:Data_Quality_Rule_16 | 2016-02-29 | 2016-08-08 | 02     | 08     | 5   
| CDE:Data_Quality_Rule_18 | 2016-05-15 | 2016-10-31 | 05     | 10     | 6   
| CDE:Data_Quality_Rule_4  | 2016-03-28 | 2016-07-02 | 03     | 07     | 3   
| CDE:Data_Quality_Rule_5  | 2016-02-02 | 2016-06-06 | 02     | 06     | 4   

我可以获取起始月份、结束月份和持续时间。但我想在SPARQL中获取起始月份和结束月份之间的所有月份。最终结果是根据开始和结束日期获得每月数据质量规则数量计数,如下所示:
| Months   | Number Of Data Quality Rules |
|  1       | 2                        
|  2       | 4                            
|  3       | 6                            
|  4       | 3                             
|  5       | 3                            
|  6       | 4                           
|  7       | 4                            
|  8       | 4                            
|  9       | 5                             
|  10      | 3                             
|  11      | 2                             
|  12      | 5                            

这是一个有趣的问题。 :) - Joshua Taylor
做了很多研究...没有找到任何答案。非常感谢您的时间和帮助!! - Shruti Chandrika
我认为解决这些问题的关键是要认识到许多查询语言不允许你生成数据,因此你必须显式地提供它并在其上进行“连接”。在这种情况下,我们提供了一个合法的?month值列表。 - Joshua Taylor
1个回答

6

首先,我们需要一些与开始和结束日期相关的数据:

@prefix : <urn:ex:>
@prefix xsd: <http://www.w3.org/2001/XMLSchema#>

:rule1 :begin "2011-01-10T14:45:13.815-05:00"^^xsd:dateTime ;
       :end   "2011-06-10T14:45:13.815-05:00"^^xsd:dateTime .

:rule2 :begin "2011-04-10T14:45:13.815-05:00"^^xsd:dateTime ;
       :end   "2011-10-10T14:45:13.815-05:00"^^xsd:dateTime .

:rule3 :begin "2011-06-10T14:45:13.815-05:00"^^xsd:dateTime ;
       :end   "2011-11-10T14:45:13.815-05:00"^^xsd:dateTime .

然后,您可以编写一个查询,获取每个规则处于活动状态的月份。如果您按月份分组,然后计算规则数量,您将获得每个月份中活动规则的数量:

prefix : <urn:ex:>
prefix xsd: <http://www.w3.org/2001/XMLSchema#>

select ?rule ?month {
  #-- Specify the possible values for ?month
  #-- in advance.  These are just the numbers
  #-- one through twelve.
  values ?month { 1 2 3 4 5 6 7 8 9 10 11 12 }

  #-- Get the begin and end dates of that
  #-- you're interested in.  The way you
  #-- do this depends on the structure of
  #-- your data, of course.
  ?rule :begin ?begin ; :end ?end .

  #-- Then take only the values of ?month
  #-- that are between the beginning month
  #-- and the ending month.
  filter ( month(?begin) <= ?month && ?month <= month(?end) )
}

------------------
| rule   | month |
==================
| :rule1 | 1     |
| :rule1 | 2     |
| :rule1 | 3     |
| :rule1 | 4     |
| :rule1 | 5     |
| :rule1 | 6     |
| :rule2 | 4     |
| :rule2 | 5     |
| :rule2 | 6     |
| :rule2 | 7     |
| :rule2 | 8     |
| :rule2 | 9     |
| :rule2 | 10    |
| :rule3 | 6     |
| :rule3 | 7     |
| :rule3 | 8     |
| :rule3 | 9     |
| :rule3 | 10    |
| :rule3 | 11    |
------------------

现在你可以按月份对这些结果进行分组,然后计算每个月的规则数量:
prefix : <urn:ex:>
prefix xsd: <http://www.w3.org/2001/XMLSchema#>

select ?month (count(distinct ?rule) as ?numRules) where {
  values ?month { 1 2 3 4 5 6 7 8 9 10 11 12 }

  ?rule :begin ?begin ; :end ?end .

  filter ( month(?begin) <= ?month && ?month <= month(?end) )
}
group by ?month

--------------------
| month | numRules |
====================
| 1     | 1        |
| 2     | 1        |
| 3     | 1        |
| 4     | 2        |
| 5     | 2        |
| 6     | 3        |
| 7     | 2        |
| 8     | 2        |
| 9     | 2        |
| 10    | 2        |
| 11    | 1        |
--------------------

这个结果没有包括第12个月份,因为当时没有任何有效规则。如果您想列出所有月份,可以将规则匹配部分设为可选:

prefix : <urn:ex:>
prefix xsd: <http://www.w3.org/2001/XMLSchema#>

select ?month (count(distinct ?rule) as ?numRules) {
  values ?month { 1 2 3 4 5 6 7 8 9 10 11 12 }

  optional {
    ?rule :begin ?begin ; :end ?end .
    filter ( month(?begin) <= ?month && ?month <= month(?end) )
  }
}
group by ?month

--------------------
| month | numRules |
====================
| 1     | 1        |
| 2     | 1        |
| 3     | 1        |
| 4     | 2        |
| 5     | 2        |
| 6     | 3        |
| 7     | 2        |
| 8     | 2        |
| 9     | 2        |
| 10    | 2        |
| 11    | 1        |
| 12    | 0        |
--------------------

2
谢谢 Joshua...它成功了!昨天以来一直在试图解决这个问题!你太棒了! - Shruti Chandrika

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接