Search code examples
sparqlwikidatawikidata-query-service

Wikidata Query: Find American authors of children’s fiction


I want to find all children's fiction writers using Wikidata SPARQL query. But I couldn't figure out how? Can someone help, please? The following is my approach but I don't think it is the correct way.

SELECT ?item ?itemLabel {
?item wdt:P31 wd:Q5. #find humans
?item wdt:P106 wd: #humans whose occupation is a novelist
[another condition needed] #children's fiction.
SERVICE wikibase:label {bd:serviceParam wikibase:language 'en'.}
} LIMIT 10

Solution

  • There is not one correct way, especially not in Wikidata where not all items of the same kind necessarily have the same properties.

    One way would be to find the authors of works that are intended for (P2360) children:

    # it’s a literary work (incl. any sublasses)
    ?book wdt:P31/wdt:P279* wd:Q7725634 .
      
    # the literary work is intended for children
    ?book wdt:P2360 wd:Q7569 .
      
    # the literary work has an author
    ?book wdt:P50 ?author .
      
    # the author is a US citizen
    ?author wdt:P27 wd:Q30 .
    

    Instead of getting all works that belong to the class "literary work" or any of its subclasses, you could decide to use only the class "fiction literature" (Q38072107) instead; with the risk that not all relevant works use this class.

    Another way would be to find all authors that have "children’s writer" (Q4853732), or any of its subclasses, as occupation:

    ?author wdt:P106/wdt:P279* wd:Q4853732 .
    
    ?author wdt:P27 wd:Q30 .
    

    As the different ways might find different results, you could could use them in the same query, using UNION:

    SELECT DISTINCT ?author ?authorLabel
    WHERE {
      
      { 
        # way 1 
      }
      UNION
      { 
        # way 2
      }
      UNION
      { 
        # way 3
      } 
    
    
      SERVICE wikibase:label {bd:serviceParam wikibase:language 'en'.}
      
    }