带有 2 个 WHERE 和 2 个 GROUP BY 的 Sparql 聚合查询?

问题描述 投票:0回答:1

我正在使用包含乐队、他们的专辑和专辑发行日期的数据库。 我正在尝试获取一个表格,其中一列表示 1980 年代发行的专辑数量,一列表示 1990 年代发行的专辑数量。

我期望有这样的返回表:

乐队 80 年代专辑 90 年代专辑
12 1
5 3

这是我目前的尝试:

SELECT ?band (COUNT(?album1980s) as ?numalbum1980s) (COUNT(?album1990s) as ?numalbum1990s)
WHERE {
   ?album1980s :artist ?band .
   ?album1980s :date ?1980sdate
   BIND(YEAR(?1980sdate) as ?1980syear)
   FILTER(?1980syear > 1970 && ?1980syear < 1990)
}
GROUP BY ?band
UNION
WHERE {
   ?album1990s :artist ?band .
   ?album1990s :date ?1990sdate
   BIND(YEAR(?1990sdate) as ?1990syear)
   FILTER(?1990syear > 1990 && ?1990syear < 2000)
}
GROUP BY ?band

这产生了这个:

乐队 numalbum1980 90 年代专辑
12 0
5 0

如您所见,查询结果完全缺少第二个 WHERE 子句中的任何内容。我在 numalbum1980s col 中得到了正确的计数,但在 numalbum1990s col 中只有零。

我还尝试将两个 WHERE 子句封装在一个子句中,但该查询格式错误:

SELECT ?band (COUNT(?album1980s) as ?numalbum1980s) (COUNT(?album1990s) as ?numalbum1990s)
{
WHERE {
   ?album1980s :date ?1980sdate
   BIND(YEAR(?1980sdate) as ?1980syear)
   FILTER(?1980syear > 1970 && ?1980syear < 1990)
}
UNION
WHERE {

   ?album1990s :date ?1990sdate
   BIND(YEAR(?1990sdate) as ?1990syear)
   FILTER(?1990syear > 1990 && ?1990syear < 2000)
}
   ?album1980s :artist ?band .
   ?album1990s :artist ?band .
}
GROUP BY ?band

如果您有任何解决方案的想法,我很想听听。 (我目前正在cloud.stardog.com使用SPARQL接口,但我认为接口并不重要。)

sparql rdf graph-databases stardog
1个回答
0
投票

你需要的是

JOIN
而不是
UNION
:

SELECT * {
  {
     SELECT ?band (COUNT(DISTINCT ?work) AS ?1980s) {
        VALUES ?band {wd:Q18233 wd:Q371938}
        ?work wdt:P31 wd:Q482994 .
        ?work wdt:P175 ?band .
        ?work wdt:P577 ?date .
        BIND (YEAR(?date) AS ?year) 
        FILTER (?year >= 1980 && ?year < 1990)
     }  GROUP BY ?band
  }
  # .
  {
     SELECT ?band (COUNT(DISTINCT ?work) AS ?1990s) {
        VALUES ?band {wd:Q18233 wd:Q371938}
        ?work wdt:P31 wd:Q482994 .
        ?work wdt:P175 ?band .
        ?work wdt:P577 ?date .
        BIND (YEAR(?date) AS ?year) 
        FILTER (?year >= 1990 && ?year < 2000)
     }  GROUP BY ?band
  }
}

或者更确切地说是

SUM
而不是
COUNT

SELECT ?band (SUM(?1980) AS ?1980s) (SUM(?1990) AS ?1990s) {
   VALUES ?band {wd:Q18233 wd:Q371938}
   ?work wdt:P31 wd:Q482994 .
   ?work wdt:P175 ?band .
   ?work wdt:P577 ?date .
   BIND (YEAR(?date) AS ?year) 
   BIND ( IF(?year >= 1980 && ?year < 1990, 1, 0) AS ?1980)
   BIND ( IF(?year >= 1990 && ?year < 2000, 1, 0) AS ?1990)
} GROUP BY ?band
© www.soinside.com 2019 - 2024. All rights reserved.