Nijenhof
Nijenhof

Reputation: 692

How to filter for a condition with two columns?

For a course I follow I have to write several SPARQL queries about Lego sets. I am interested in finding out if there is a Lego theme which has a single package type.

I have the following SPARQL query:

select distinct ?theme ?package_type (count(?theme) as ?amount_of_lego_sets)
where{
    ?Lego_set rdf:type wd:Q58780257 .
    ?Lego_set sch:audienceType ?audience .
    ?Lego_set ex:has_package_information ?package_info .
    ?audience ex:belongs_to_theme ?theme .
    ?package_info ex:has_packaging_type ?package_type .
} group by ?theme ?package_type
order by ?theme

Which produces the following output: enter image description here

As you can see there is one set that has the theme “4 Juniors” and the package type “Polybag”. Now, I am interested in themes like Advanced models or Action Wheelers which only have a single package type. However, I found it challenging to filter for these themes.

What modification to my query could I implement to remove themes which have sets that have more than one package type?

Upvotes: 2

Views: 137

Answers (1)

Valerio Cocchi
Valerio Cocchi

Reputation: 1966

This is an interesting question. I would use FILTER NOT EXISTS to add an atom to the query body, where we make sure that the theme doesn't have two types of packages, like this:

FILTER NOT EXISTS {
 ?Lego_set2 sch:audienceType ?audience2 .
 ?Lego_set2 ex:has_package_information ?package_info2 .
 #Notice that the 'theme' variable must be the same as the outer query
 ?audience2 ex:belongs_to_theme ?theme . 
 ?package_info2 ex:has_packaging_type ?package_type1, ?package_type2 
FILTER(?pakage_type1 != ?package_type2)}

Thus your full query should be something like:

    select distinct ?theme ?package_type (count(?theme) as ?amount_of_lego_sets)
    where{
    ?Lego_set rdf:type wd:Q58780257 .
    ?Lego_set sch:audienceType ?audience .
    ?Lego_set ex:has_package_information ?package_info .
    ?audience ex:belongs_to_theme ?theme .
    ?package_info ex:has_packaging_type ?package_type .
    FILTER NOT EXISTS {
     ?Lego_set2 sch:audienceType ?audience2 .
     ?Lego_set2 ex:has_package_information ?package_info2 .
     #Notice that the 'theme' variable must be the same as the outer query
     ?audience2 ex:belongs_to_theme ?theme . 
     ?package_info2 ex:has_packaging_type ?package_type1, ?package_type2 
    FILTER(?pakage_type1 != ?package_type2)}

} group by ?theme ?package_type
order by ?theme

You could also use the aggregation approach mentioned in the comments, but hopefully this one solves your problem.

Upvotes: 1

Related Questions