Sparql Select only one label and comment of classes - select

I am trying to select one label and comment of classes but group by doesn't work as expected. The following query is an example of the select.
SELECT ?class ?label ?comment WHERE
{
{SELECT DISTINCT ?class WHERE { {?uri rdf:type ?class}UNION {?class rdf:type owl:Class} UNION {?class rdf:type rdfs:Class} }OFFSET 0 LIMIT 100}
.optional{?class rdfs:label ?label}
.optional{?class rdfs:comment ?comment}
}GROUP BY ?class
The goal is to to have every class uri with one label and comment
But am getting results as :
http://dbpedia.org/ontology/Activity "attività"#it
http://dbpedia.org/ontology/Activity "活動"#ja
Any idea ?

Your query is actually illegal - it uses non-aggregate, non-group key in the outer SELECT.
You need to use "SAMPLE" to one pick (random) item from a group if you think there might be multiple labels or comments.
SELECT ?class (sample(?labelX) as ?label) (sample(?commentX) as ?comment) WHERE
{
SELECT DISTINCT ?class {
{?uri rdf:type ?class} UNION
{?class rdf:type owl:Class} UNION
{?class rdf:type rdfs:Class}
} LIMIT 100
optional{?class rdfs:label ?labelX}
optional{?class rdfs:comment ?commentX}
} GROUP BY ?class

Related

sparql select wikidata group_by and concat

I want to extract a list o players and a list of clubs where it has played, separated by commas.
SELECT DISTINCT ?playerLabel
(GROUP_CONCAT(?teamLabel ; separator=',') as ?teams)
WHERE {
?player wdt:P106 wd:Q937857 .
?player wdt:P2574 ?team
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }
}
GROUP BY ?playerLabel
I have two problems:
I don't get a list of teams for each player, only the name, and variable ?teams empty.
If I don't use GROUP CONCAT and GROUP BY I obtain the team id, but I prefer the label of team.
For example 2 players...:
playerLabel teams
Cristiano Ronaldo Sporting Portugal, Manchester U, Real Madrid, Juventus, Manchester U
Leo Messi Barcelona, PSG
At least I need the Concat and group by, even with code...
thanks
You use P2574, which is "National-Football-Teams.com player ID". While National-Football-Teams.com lists all teams a player played for, this data is not accessible through the Wikidata Query Service. But Wikidata itself has a dedicated property for sports team member: P54.
So write ?player wdt:P54 ?team instead of ?player wdt:P2574 ?team.
Additionaly, you need to add ?team rdfs:label ?teamLabel . filter (lang(?teamLabel)='en') to be able to use ?teamLabel in GROUP_CONCAT().
Thus, the full working query looks like this (restricted to US players to avoid query time outs):
SELECT DISTINCT ?playerLabel (GROUP_CONCAT(?teamLabel ; separator=',') as ?teams)
WHERE {
?player wdt:P106 wd:Q937857 .
?player wdt:P27 wd:Q30 .
?player wdt:P54 ?team .
?team rdfs:label ?teamLabel . filter (lang(?teamLabel)='en')
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }
}
GROUP BY ?playerLabel

PostgreSql Group By and aggreate function error

My problem is, when I run the following query in MySQL, it looks like this
Query;
SELECT
CONCAT(b.tarih, '#', CONCAT(b.enlem, ',', b.boylam), '#', b.aldigi_yol) AS IlkMesaiEnlemBoylamImei,
CONCAT(tson.max_tarih, '#', CONCAT(tson.max_enlem, ',', tson.max_boylam), '#', tson.max_aldigi_yol) AS SonMesaiEnlemBoylamImei,
Max(CAST(b.hiz AS UNSIGNED)) As EnYuksekHiz,
TIME_FORMAT(Sec_TO_TIME(TIMESTAMPDIFF(SECOND, (b.tarih), (tson.max_tarih))), '%H:%i') AS DurmaSuresi
FROM
(Select id as max_id, tarih as max_tarih, enlem as max_enlem, boylam as max_boylam, aldigi_yol as max_aldigi_yol from _213gl2015016424 where id in(
SELECT MAX(id)
FROM _213gl2015016424 where (tarih between DATE('2016-11-30 05:45:00') AND Date('2017-01-13 14:19:06')) AND CAST(hiz AS UNSIGNED) > 0
GROUP BY DATE(tarih))
) tson
LEFT JOIN _213gl2015016424 a ON a.id = tson.max_id
LEFT JOIN _213gl2015016424 b ON DATE(b.tarih) = DATE(a.tarih)
WHERE b.tarih is not null And (b.tarih between DATE('2016-11-30 05:45:00') AND Date('2017-01-13 14:19:06')) AND b.hiz > 0
GROUP BY tson.max_tarih
Output is order by date;
Result query
When I try to run a query in PostgreSQL, I get group by mistake.
Query;
SELECT
CONCAT(b.tarih, '#', CONCAT(b.enlem, ',', b.boylam), '#', b.toplamyol) AS IlkMesaiEnlemBoylamImei,
CONCAT(tson.max_tarih, '#', CONCAT(tson.max_enlem, ',', tson.max_boylam), '#', tson.max_toplamyol) AS SonMesaiEnlemBoylamImei,
Max(CAST(b.hiz AS OID)) As EnYuksekHiz,
to_char(to_timestamp((extract(epoch from (tson.max_tarih)) - extract(epoch from (b.tarih)))) - interval '2 hour','HH24:MI') AS DurmaSuresi
FROM
(Select id as max_id, tarih as max_tarih, enlem as max_enlem, boylam as max_boylam, toplamyol as max_toplamyol from _213GL2016008691 where id in(
SELECT MAX(id)
FROM _213GL2016008691 where (tarih between DATE('2018-02-01 03:31:54') AND DATE('2018-03-01 03:31:54')) AND CAST(hiz AS OID) > 0
GROUP BY DATE(tarih))
) tson
LEFT JOIN _213GL2016008691 a ON a.id = tson.max_id
LEFT JOIN _213GL2016008691 b ON DATE(b.tarih) = DATE(a.tarih)
WHERE b.tarih is not null And (b.tarih between DATE('2018-02-12 03:31:54') AND DATE('2018-02-13 03:31:54')) AND b.hiz > 0
GROUP BY tson.max_tarih
Group by error is : To use the aggregate function, you must add the column "b.tarih" to the GROUP BY list.
When I add it I get the same error for another column.I'm waiting for your help.
You are using a feature of MySQL that is not standard SQL and you can also deactivate.
You are grouping by tson.max_tarih in your query. That means that for all rows that share the same value in that field, you will get only one row as a result of that group.
If you have several different values in the rest of the fields (enlem, boylam, etc...) which one are you trying to get in as the result of the query? That's the question that PostgreSQL is asking you.
MySQL is just returning any value for those fields among the rows in the group. PostgreSQL requires you to actually specify it.
Two typical solutions would be grouping by the rest of the fields (b.tarih, b.enlem) or specifying the value those fields to something like MAX(b.tarih), etc.

Laravel 5, Derived table in join clause?

I have this query:
SELECT * FROM blog
LEFT JOIN (
SELECT blog_id, AVG(value) as blog_rating FROM blog_ratings
GROUP BY (blog_id)
) T ON T.blog_id = blog.id;
I do not know how to write this with Eloquent.
For Example:
Blog::select("*")->leftJoin( /* Here goes derived table */ )->get()
How do I accomplish this?
I'd personally just use the fluent query builder, try this out and see how it works out:
DB::table('blog')
->select('*')
->leftJoin(DB::raw('(SELECT blog_id, AVG(value) as blog_rating FROM blog_ratings
GROUP BY (blog_id)
) as T'), function ($join) {
$join->on ( 'T.blog_id', '=', 'blog.id' );
})
->get();
You can always swap ->get() for ->toSql() to dump out the query and adjust if you see any mistakes.

SPARQL query restrict answers

hey im trying to get all the receipes that only contains some ingredients. For example if I have a receipe with tomato and bread and I only said that Im going to use tomate that receipe shouldnt show up. If I have any receipe with only this ingredient then it should show up. I did the following query:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>`
PREFIX rec:<http://www.receta.org#>
SELECT reduced ?r
WHERE {
?x rdf:type rec:Receta .
?x rdfs:label ?r.
?x rec:Ingrediente rec:Tomato.
?x rec:Ingrediente ?i.
FILTER (?i=rec:Tomato)
}
But the problem is that it shows all the receipes that contains that ingredient and much more. How can I restrict this? Can someone help me?
Your first query
SELECT reduced ?r WHERE {
?x rdf:type rec:Receta .
?x rdfs:label ?r.
?x rec:Ingrediente rec:Tomato.
?x rec:Ingrediente ?i.
FILTER (?i=rec:Tomato)
}
matches any recipe that has Tomato as some ingredient. Using a filter with a constant value like that is the same as having written:
SELECT reduced ?r WHERE {
?x rdf:type rec:Receta .
?x rdfs:label ?r.
?x rec:Ingrediente rec:Tomato.
}
Instead, you want to select recipes and remove those that have ingredients other than some set. AndyS's answer mentions filter not exist, and that's a start. Specifically, if you want to ensure that all the ingredients are, e.g., Tomato, Basil, and Cheese, then you would write a query like:
SELECT reduced ?r WHERE {
?x rdf:type rec:Receta .
?x rdfs:label ?r.
filter not exists {
?x rec:Ingrediente ?i
filter( ?i not in (rec:Tomato, rec:Basil rec:Cheese) )
}
This finds all recipes, and then removes any which have an ingredient which is not one of the allowed ingredients.
Look at FILTER NOT EXISTS.
So something like (depends of the exact nature of your data that isn't shown):
WHERE {
?x rdf:type rec:Receta .
?x rdfs:label ?r.
FILTER NOT EXISTS {?x rec:Ingrediente rec:Tomato }
}
which is all ?x, ?r where ?x does not have property/value "rec:Ingrediente rec:Tomato".

How can I fix Unicode issues in the dataset returned from my SPARQL query?

At the moment, I am getting rows with Unicode decode issues, while using SPARQL on Dbpedia (using Virtuoso servers). This is an example of what I am getting Knut %C3%85ngstr%C3%B6m.
The right name is Knut Ångström. Cool, now how do I fix this? My crafted query is:
select distinct (strafter(str(?influencerString),str(dbpedia:)) as ?influencerString) (strafter(str(?influenceeString),str(dbpedia:)) as ?influenceeString) where {
{ ?influencer a dbpedia-owl:Person . ?influencee a dbpedia-owl:Person .
?influencer dbpedia-owl:influenced ?influencee .
bind( replace( str(?influencer), "_", " " ) as ?influencerString )
bind( replace( str(?influencee), "_", " " ) as ?influenceeString )
}
UNION
{ ?influencee a dbpedia-owl:Person . ?influencer a dbpedia-owl:Person .
?influencee dbpedia-owl:influencedBy ?influencer .
bind( replace( str(?influencee), "_", " " ) as ?influenceeString )
bind( replace( str(?influencer), "_", " " ) as ?influencerString )
}
}
The DBpedia wiki explains that the identifiers for resources in the English DBpedia dataset use URIs, not IRIs, which means that you'll end up with encoding issues like this.
3. Denoting or Naming “things”
Each thing in the DBpedia data set is denoted by a de-referenceable
IRI- or URI-based reference of the form
http://dbpedia.org/resource/Name, where Name is derived from the URL
of the source Wikipedia article, which has the form
http://en.wikipedia.org/wiki/Name. Thus, each DBpedia entity is tied
directly to a Wikipedia article. Every DBpedia entity name resolves to
a description-oriented Web document (or Web resource).
Until DBpedia release 3.6, we only used article names from the English
Wikipedia, but since DBpedia release 3.7, we also provide localized
datasets that contain IRIs like http://xx.dbpedia.org/resource/Name,
where xx is a Wikipedia language code and Name is taken from the
source URL, http://xx.wikipedia.org/wiki/Name.
Starting with DBpedia release 3.8, we use IRIs for most DBpedia entity
names. IRIs are more readable and generally preferable to URIs, but
for backwards compatibility, we still use URIs for DBpedia resources
extracted from the English Wikipedia and IRIs for all other languages.
Triples in Turtle files use IRIs for all languages, even for English.
There are several details on the encoding of URIs that should always
be taken into account.
In this particular case, it looks like you don't really need to break up the identifier so much as get a label for the entity.
## If things were guaranteed to have just one English label,
## we could simply take ?xLabel as the value that we want with
## `select ?xLabel { … }`, but since there might be more than
## one, we can group by `?x` and then take a sample from the
## set of labels for each `?x`.
select (sample(?xLabel) as ?label) {
?x dbpedia-owl:influenced dbpedia:August_Kundt ;
rdfs:label ?xLabel .
filter(langMatches(lang(?xLabel),"en"))
}
group by ?x
SPARQL results
Simplifying your query a bit, we can have this:
select
(sample(?rLabel) as ?influencerName)
(sample(?eLabel) as ?influenceeName)
where {
?influencer dbpedia-owl:influenced|^dbpedia-owl:influencedBy ?influencee .
dbpedia-owl:Person ^a ?influencer, ?influencee .
?influencer rdfs:label ?rLabel .
filter( langMatches(lang(?rLabel),"en") )
?influencee rdfs:label ?eLabel .
filter( langMatches(lang(?eLabel),"en") )
}
group by ?influencer ?influencee
SPARQL results
If you don't want language tags on those results, then add a call to str():
select
(str(sample(?rLabel)) as ?influencerName)
(str(sample(?eLabel)) as ?influenceeName)
where {
?influencer dbpedia-owl:influenced|^dbpedia-owl:influencedBy ?influencee .
dbpedia-owl:Person ^a ?influencer, ?influencee .
?influencer rdfs:label ?rLabel .
filter( langMatches(lang(?rLabel),"en") )
?influencee rdfs:label ?eLabel .
filter( langMatches(lang(?eLabel),"en") )
}
group by ?influencer ?influencee
SPARQL results