Claude Code Plugins

Community-maintained marketplace

Feedback

lang-sparql-dev

@aRustyDev/ai
0
0

Foundational SPARQL patterns covering RDF querying, triple patterns, graph patterns, and semantic web fundamentals. Use when querying RDF data or working with knowledge graphs. This is the entry point for SPARQL development.

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name lang-sparql-dev
description Foundational SPARQL patterns covering RDF querying, triple patterns, graph patterns, and semantic web fundamentals. Use when querying RDF data or working with knowledge graphs. This is the entry point for SPARQL development.

SPARQL Development Skill

Comprehensive foundational patterns for SPARQL (SPARQL Protocol and RDF Query Language), covering RDF fundamentals, query patterns, graph operations, and semantic web development.

Table of Contents

RDF Fundamentals

Triple Structure

RDF data is represented as triples: Subject-Predicate-Object.

# Basic triple pattern
<http://example.org/person/Alice>
    <http://xmlns.com/foaf/0.1/name>
    "Alice Smith" .

# Compact notation with prefixes
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX ex: <http://example.org/>

ex:person/Alice foaf:name "Alice Smith" .

URI Types

# Full URI
<http://example.org/resource/123>

# Prefixed name
PREFIX ex: <http://example.org/>
ex:resource/123

# Blank nodes (anonymous resources)
_:node1
[]

# Literals
"Plain string"
"String with language"@en
"42"^^xsd:integer
"2024-01-15"^^xsd:date

Literal Types

PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>

# String literals
"Simple string"
"String with language"@en
"Multi-line
string"

# Numeric literals
42
3.14
"100"^^xsd:integer
"99.99"^^xsd:decimal

# Boolean literals
true
false
"true"^^xsd:boolean

# Date/Time literals
"2024-01-15"^^xsd:date
"14:30:00"^^xsd:time
"2024-01-15T14:30:00Z"^^xsd:dateTime

# Other common types
"http://example.org"^^xsd:anyURI
"PT1H30M"^^xsd:duration

RDF Graphs

# Default graph (unnamed)
SELECT * WHERE {
    ?s ?p ?o .
}

# Named graphs
SELECT * WHERE {
    GRAPH <http://example.org/graph1> {
        ?s ?p ?o .
    }
}

# Query across multiple graphs
SELECT * WHERE {
    {
        GRAPH <http://example.org/graph1> {
            ?s ?p ?o .
        }
    }
    UNION
    {
        GRAPH <http://example.org/graph2> {
            ?s ?p ?o .
        }
    }
}

# Query from all graphs
SELECT * WHERE {
    GRAPH ?g {
        ?s ?p ?o .
    }
}

RDF Collections

# RDF Lists (linked list structure)
PREFIX ex: <http://example.org/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

ex:myList rdf:first "Item 1" ;
          rdf:rest [ rdf:first "Item 2" ;
                     rdf:rest [ rdf:first "Item 3" ;
                                rdf:rest rdf:nil ] ] .

# Shorthand syntax
ex:myList rdf:value ( "Item 1" "Item 2" "Item 3" ) .

# Querying lists
SELECT ?item WHERE {
    ?list rdf:rest*/rdf:first ?item .
}

Basic Query Patterns

SELECT Queries

PREFIX foaf: <http://xmlns.com/foaf/0.1/>

# Basic SELECT
SELECT ?name WHERE {
    ?person foaf:name ?name .
}

# Multiple variables
SELECT ?person ?name ?email WHERE {
    ?person foaf:name ?name ;
            foaf:mbox ?email .
}

# SELECT DISTINCT (remove duplicates)
SELECT DISTINCT ?type WHERE {
    ?s a ?type .
}

# SELECT * (all variables)
SELECT * WHERE {
    ?s ?p ?o .
}

# SELECT with expressions
SELECT ?person ?age (?age + 10 AS ?ageIn10Years) WHERE {
    ?person foaf:age ?age .
}

WHERE Clause Patterns

PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX ex: <http://example.org/>

# Basic triple pattern
SELECT ?name WHERE {
    ex:Alice foaf:name ?name .
}

# Multiple triple patterns (implicit AND)
SELECT ?name ?email WHERE {
    ?person foaf:name ?name .
    ?person foaf:mbox ?email .
}

# Shorthand for same subject (semicolon)
SELECT ?name ?email WHERE {
    ?person foaf:name ?name ;
            foaf:mbox ?email .
}

# Shorthand for same subject and predicate (comma)
SELECT ?person ?friend WHERE {
    ?person foaf:name "Alice" ;
            foaf:knows ?friend1, ?friend2 .
}

# Nested patterns
SELECT ?person ?friendName WHERE {
    ?person foaf:name "Alice" .
    ?person foaf:knows ?friend .
    ?friend foaf:name ?friendName .
}

Filtering Results

PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>

# String filtering
SELECT ?person ?name WHERE {
    ?person foaf:name ?name .
    FILTER (regex(?name, "Smith", "i"))  # Case-insensitive
}

# Numeric filtering
SELECT ?person ?age WHERE {
    ?person foaf:age ?age .
    FILTER (?age >= 18 && ?age < 65)
}

# Type checking
SELECT ?person ?value WHERE {
    ?person foaf:name ?value .
    FILTER (isLiteral(?value))
}

# Language filtering
SELECT ?label WHERE {
    ?resource rdfs:label ?label .
    FILTER (lang(?label) = "en")
}

# Negation
SELECT ?person ?name WHERE {
    ?person foaf:name ?name .
    FILTER (!bound(?person))  # Where variable is not bound
}

# String functions in FILTER
SELECT ?name WHERE {
    ?person foaf:name ?name .
    FILTER (
        strlen(?name) > 5 &&
        contains(?name, "Smith") &&
        strstarts(?name, "J")
    )
}

# Date filtering
SELECT ?event ?date WHERE {
    ?event ex:eventDate ?date .
    FILTER (
        ?date >= "2024-01-01"^^xsd:date &&
        ?date < "2025-01-01"^^xsd:date
    )
}

# Multiple conditions
SELECT ?person WHERE {
    ?person foaf:age ?age ;
            foaf:name ?name .
    FILTER (
        (?age > 18 && ?age < 65) ||
        (regex(?name, "^Admin"))
    )
}

Binding Values

PREFIX foaf: <http://xmlns.com/foaf/0.1/>

# BIND - assign values to variables
SELECT ?person ?name ?greeting WHERE {
    ?person foaf:name ?name .
    BIND (CONCAT("Hello, ", ?name) AS ?greeting)
}

# Multiple BIND statements
SELECT ?x ?squared ?cubed WHERE {
    VALUES ?x { 1 2 3 4 5 }
    BIND (?x * ?x AS ?squared)
    BIND (?x * ?x * ?x AS ?cubed)
}

# BIND with conditionals
SELECT ?person ?ageGroup WHERE {
    ?person foaf:age ?age .
    BIND (
        IF(?age < 18, "Minor",
        IF(?age < 65, "Adult", "Senior"))
        AS ?ageGroup
    )
}

# COALESCE - first non-null value
SELECT ?person ?contact WHERE {
    ?person foaf:mbox ?email .
    OPTIONAL { ?person foaf:phone ?phone }
    BIND (COALESCE(?phone, ?email) AS ?contact)
}

VALUES Clause

PREFIX ex: <http://example.org/>

# Inline data
SELECT ?person ?name WHERE {
    ?person ex:name ?name .
    VALUES ?person {
        ex:Alice
        ex:Bob
        ex:Charlie
    }
}

# Multiple variables
SELECT ?person ?age WHERE {
    VALUES (?person ?age) {
        (ex:Alice 30)
        (ex:Bob 25)
        (ex:Charlie 35)
    }
    ?person ex:name ?name .
}

# Mixing bound and unbound values
SELECT ?x ?y WHERE {
    VALUES (?x ?y) {
        (1 UNDEF)
        (2 3)
        (UNDEF 4)
    }
}

Graph Patterns

OPTIONAL Patterns

PREFIX foaf: <http://xmlns.com/foaf/0.1/>

# Basic OPTIONAL
SELECT ?person ?name ?email WHERE {
    ?person foaf:name ?name .
    OPTIONAL { ?person foaf:mbox ?email }
}

# Multiple OPTIONAL blocks
SELECT ?person ?name ?email ?phone WHERE {
    ?person foaf:name ?name .
    OPTIONAL { ?person foaf:mbox ?email }
    OPTIONAL { ?person foaf:phone ?phone }
}

# Nested OPTIONAL
SELECT ?person ?friend ?friendEmail WHERE {
    ?person foaf:name "Alice" .
    OPTIONAL {
        ?person foaf:knows ?friend .
        OPTIONAL { ?friend foaf:mbox ?friendEmail }
    }
}

# OPTIONAL with FILTER
SELECT ?person ?name ?age WHERE {
    ?person foaf:name ?name .
    OPTIONAL {
        ?person foaf:age ?age .
        FILTER (?age >= 18)
    }
}

UNION Patterns

PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX vcard: <http://www.w3.org/2006/vcard/ns#>

# Basic UNION
SELECT ?name WHERE {
    {
        ?person foaf:name ?name .
    }
    UNION
    {
        ?person vcard:fn ?name .
    }
}

# Multiple UNIONs
SELECT ?contact WHERE {
    {
        ?person foaf:mbox ?contact .
    }
    UNION
    {
        ?person foaf:phone ?contact .
    }
    UNION
    {
        ?person vcard:email ?contact .
    }
}

# UNION with different patterns
SELECT ?person ?label WHERE {
    {
        ?person foaf:name ?label .
        ?person foaf:age ?age .
        FILTER (?age > 18)
    }
    UNION
    {
        ?person rdfs:label ?label .
        ?person a foaf:Organization .
    }
}

MINUS Patterns

PREFIX foaf: <http://xmlns.com/foaf/0.1/>

# Exclude patterns
SELECT ?person ?name WHERE {
    ?person foaf:name ?name .
    MINUS {
        ?person foaf:mbox ?email .
    }
}

# Multiple MINUS
SELECT ?person WHERE {
    ?person a foaf:Person .
    MINUS { ?person foaf:age ?age }
    MINUS { ?person foaf:mbox ?email }
}

# MINUS vs OPTIONAL + FILTER NOT EXISTS
# These are similar but have subtle differences
SELECT ?person ?name WHERE {
    ?person foaf:name ?name .
    FILTER NOT EXISTS {
        ?person foaf:mbox ?email .
    }
}

NOT EXISTS Patterns

PREFIX foaf: <http://xmlns.com/foaf/0.1/>

# Basic negation
SELECT ?person WHERE {
    ?person a foaf:Person .
    FILTER NOT EXISTS {
        ?person foaf:knows ?other .
    }
}

# Complex negation
SELECT ?person WHERE {
    ?person foaf:name ?name .
    FILTER NOT EXISTS {
        ?person foaf:knows ?friend .
        ?friend foaf:mbox ?email .
    }
}

# Combination with EXISTS
SELECT ?person WHERE {
    ?person a foaf:Person .
    FILTER EXISTS { ?person foaf:name ?name }
    FILTER NOT EXISTS { ?person foaf:mbox ?email }
}

Graph Patterns

PREFIX ex: <http://example.org/>

# Query specific named graph
SELECT ?s ?p ?o WHERE {
    GRAPH ex:graph1 {
        ?s ?p ?o .
    }
}

# Query variable graph
SELECT ?g ?s ?p WHERE {
    GRAPH ?g {
        ?s ?p ?o .
    }
}

# Combine default and named graphs
SELECT ?person ?name WHERE {
    # From default graph
    ?person a foaf:Person .

    # From named graph
    GRAPH ex:privateData {
        ?person foaf:name ?name .
    }
}

# Multiple graphs with UNION
SELECT ?s ?p ?o WHERE {
    {
        GRAPH ex:graph1 { ?s ?p ?o }
    }
    UNION
    {
        GRAPH ex:graph2 { ?s ?p ?o }
    }
}

Subqueries

PREFIX foaf: <http://xmlns.com/foaf/0.1/>

# Basic subquery
SELECT ?person ?friendCount WHERE {
    ?person a foaf:Person .
    {
        SELECT ?person (COUNT(?friend) AS ?friendCount) WHERE {
            ?person foaf:knows ?friend .
        }
        GROUP BY ?person
    }
}

# Nested subqueries
SELECT ?person ?name ?avgFriendAge WHERE {
    ?person foaf:name ?name .
    {
        SELECT ?person (AVG(?friendAge) AS ?avgFriendAge) WHERE {
            ?person foaf:knows ?friend .
            ?friend foaf:age ?friendAge .
        }
        GROUP BY ?person
    }
}

# Subquery with LIMIT
SELECT ?person ?topFriend WHERE {
    ?person foaf:name ?name .
    {
        SELECT ?person ?topFriend WHERE {
            ?person foaf:knows ?topFriend .
            ?topFriend foaf:popularityScore ?score .
        }
        ORDER BY DESC(?score)
        LIMIT 1
    }
}

Query Forms

CONSTRUCT Queries

PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX vcard: <http://www.w3.org/2006/vcard/ns#>

# Basic CONSTRUCT - transform data
CONSTRUCT {
    ?person vcard:fn ?name .
    ?person vcard:email ?email .
} WHERE {
    ?person foaf:name ?name .
    OPTIONAL { ?person foaf:mbox ?email }
}

# CONSTRUCT with calculated values
CONSTRUCT {
    ?person ex:fullInfo ?info .
} WHERE {
    ?person foaf:name ?name ;
            foaf:age ?age .
    BIND (CONCAT(?name, " (", STR(?age), ")") AS ?info)
}

# CONSTRUCT with conditional patterns
CONSTRUCT {
    ?person a ex:Adult .
} WHERE {
    ?person foaf:age ?age .
    FILTER (?age >= 18)
}

# CONSTRUCT with multiple patterns
CONSTRUCT {
    ?person a ex:SocialPerson ;
            ex:friendCount ?count ;
            ex:hasFriend ?friend .
} WHERE {
    ?person foaf:knows ?friend .
    {
        SELECT ?person (COUNT(?f) AS ?count) WHERE {
            ?person foaf:knows ?f .
        }
        GROUP BY ?person
    }
}

# Empty CONSTRUCT template (copy all matching triples)
CONSTRUCT WHERE {
    ?s ?p ?o .
    FILTER (?p = foaf:knows)
}

DESCRIBE Queries

PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX ex: <http://example.org/>

# DESCRIBE specific resource
DESCRIBE ex:Alice

# DESCRIBE with variables
DESCRIBE ?person WHERE {
    ?person foaf:name "Alice Smith" .
}

# DESCRIBE multiple resources
DESCRIBE ex:Alice ex:Bob ex:Charlie

# DESCRIBE with pattern
DESCRIBE ?person ?friend WHERE {
    ?person foaf:name "Alice" .
    ?person foaf:knows ?friend .
}

# DESCRIBE all resources of a type
DESCRIBE ?person WHERE {
    ?person a foaf:Person .
}
LIMIT 10

ASK Queries

PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX ex: <http://example.org/>

# Basic ASK - check existence
ASK {
    ex:Alice foaf:knows ex:Bob .
}

# ASK with complex pattern
ASK {
    ?person foaf:name "Alice" ;
            foaf:age ?age .
    FILTER (?age >= 18)
}

# ASK with OPTIONAL
ASK {
    ex:Alice foaf:name ?name .
    OPTIONAL { ex:Alice foaf:mbox ?email }
}

# ASK with negation
ASK {
    ex:Alice a foaf:Person .
    FILTER NOT EXISTS {
        ex:Alice foaf:mbox ?email .
    }
}

Solution Modifiers

ORDER BY

PREFIX foaf: <http://xmlns.com/foaf/0.1/>

# Ascending order (default)
SELECT ?person ?age WHERE {
    ?person foaf:age ?age .
}
ORDER BY ?age

# Descending order
SELECT ?person ?age WHERE {
    ?person foaf:age ?age .
}
ORDER BY DESC(?age)

# Multiple sort keys
SELECT ?person ?lastName ?firstName WHERE {
    ?person foaf:lastName ?lastName ;
            foaf:firstName ?firstName .
}
ORDER BY ?lastName ?firstName

# Mixed sort directions
SELECT ?person ?age ?name WHERE {
    ?person foaf:age ?age ;
            foaf:name ?name .
}
ORDER BY DESC(?age) ASC(?name)

# ORDER BY with expressions
SELECT ?person ?name ?age WHERE {
    ?person foaf:name ?name ;
            foaf:age ?age .
}
ORDER BY (strlen(?name)) DESC(?age)

LIMIT and OFFSET

PREFIX foaf: <http://xmlns.com/foaf/0.1/>

# LIMIT - restrict number of results
SELECT ?person ?name WHERE {
    ?person foaf:name ?name .
}
LIMIT 10

# OFFSET - skip first N results
SELECT ?person ?name WHERE {
    ?person foaf:name ?name .
}
OFFSET 20

# Pagination with LIMIT and OFFSET
SELECT ?person ?name WHERE {
    ?person foaf:name ?name .
}
ORDER BY ?name
LIMIT 10
OFFSET 20  # Page 3 (skip first 20, show next 10)

# LIMIT with ORDER BY
SELECT ?person ?age WHERE {
    ?person foaf:age ?age .
}
ORDER BY DESC(?age)
LIMIT 5  # Top 5 oldest people

DISTINCT and REDUCED

PREFIX foaf: <http://xmlns.com/foaf/0.1/>

# DISTINCT - remove duplicates
SELECT DISTINCT ?type WHERE {
    ?s a ?type .
}

# REDUCED - allow duplicates but permit elimination
# (useful for performance optimization)
SELECT REDUCED ?type WHERE {
    ?s a ?type .
}

# DISTINCT with multiple variables
SELECT DISTINCT ?person ?type WHERE {
    ?person a ?type .
}

Projection

PREFIX foaf: <http://xmlns.com/foaf/0.1/>

# Project specific variables
SELECT ?name ?age WHERE {
    ?person foaf:name ?name ;
            foaf:age ?age ;
            foaf:mbox ?email .  # Not projected
}

# Project all variables
SELECT * WHERE {
    ?person foaf:name ?name ;
            foaf:age ?age .
}

# Project with expressions
SELECT ?person (?age + 1 AS ?nextAge) WHERE {
    ?person foaf:age ?age .
}

# Conditional projection
SELECT ?person
       (IF(?age >= 18, "Adult", "Minor") AS ?ageGroup)
WHERE {
    ?person foaf:age ?age .
}

Aggregations and Grouping

COUNT Aggregation

PREFIX foaf: <http://xmlns.com/foaf/0.1/>

# Count all results
SELECT (COUNT(*) AS ?total) WHERE {
    ?s a foaf:Person .
}

# Count specific variable
SELECT (COUNT(?friend) AS ?friendCount) WHERE {
    ex:Alice foaf:knows ?friend .
}

# Count distinct values
SELECT (COUNT(DISTINCT ?type) AS ?typeCount) WHERE {
    ?s a ?type .
}

# Count with GROUP BY
SELECT ?person (COUNT(?friend) AS ?friendCount) WHERE {
    ?person foaf:knows ?friend .
}
GROUP BY ?person

# Count with HAVING
SELECT ?person (COUNT(?friend) AS ?friendCount) WHERE {
    ?person foaf:knows ?friend .
}
GROUP BY ?person
HAVING (COUNT(?friend) > 5)

Other Aggregations

PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX ex: <http://example.org/>

# SUM
SELECT ?department (SUM(?salary) AS ?totalSalary) WHERE {
    ?person ex:department ?department ;
            ex:salary ?salary .
}
GROUP BY ?department

# AVG
SELECT ?department (AVG(?salary) AS ?avgSalary) WHERE {
    ?person ex:department ?department ;
            ex:salary ?salary .
}
GROUP BY ?department

# MIN and MAX
SELECT ?department
       (MIN(?salary) AS ?minSalary)
       (MAX(?salary) AS ?maxSalary)
WHERE {
    ?person ex:department ?department ;
            ex:salary ?salary .
}
GROUP BY ?department

# Multiple aggregations
SELECT ?person
       (COUNT(?friend) AS ?friendCount)
       (AVG(?friendAge) AS ?avgFriendAge)
       (MIN(?friendAge) AS ?youngestFriend)
       (MAX(?friendAge) AS ?oldestFriend)
WHERE {
    ?person foaf:knows ?friend .
    ?friend foaf:age ?friendAge .
}
GROUP BY ?person

# SAMPLE - arbitrary value from group
SELECT ?type (SAMPLE(?s) AS ?example) WHERE {
    ?s a ?type .
}
GROUP BY ?type

# GROUP_CONCAT - concatenate values
SELECT ?person
       (GROUP_CONCAT(?friendName; separator=", ") AS ?friends)
WHERE {
    ?person foaf:knows ?friend .
    ?friend foaf:name ?friendName .
}
GROUP BY ?person

GROUP BY Clause

PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX ex: <http://example.org/>

# Basic GROUP BY
SELECT ?type (COUNT(?s) AS ?count) WHERE {
    ?s a ?type .
}
GROUP BY ?type

# Multiple grouping variables
SELECT ?department ?location (COUNT(?person) AS ?count) WHERE {
    ?person ex:department ?department ;
            ex:location ?location .
}
GROUP BY ?department ?location

# GROUP BY with expressions
SELECT (FLOOR(?age/10) AS ?ageDecade) (COUNT(?person) AS ?count) WHERE {
    ?person foaf:age ?age .
}
GROUP BY (FLOOR(?age/10))

# Nested aggregations require subqueries
SELECT ?person ?name ?friendCount WHERE {
    ?person foaf:name ?name .
    {
        SELECT ?person (COUNT(?friend) AS ?friendCount) WHERE {
            ?person foaf:knows ?friend .
        }
        GROUP BY ?person
    }
}
ORDER BY DESC(?friendCount)

HAVING Clause

PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX ex: <http://example.org/>

# Filter groups by aggregate value
SELECT ?person (COUNT(?friend) AS ?friendCount) WHERE {
    ?person foaf:knows ?friend .
}
GROUP BY ?person
HAVING (COUNT(?friend) > 5)

# Multiple HAVING conditions
SELECT ?department
       (COUNT(?person) AS ?count)
       (AVG(?salary) AS ?avgSalary)
WHERE {
    ?person ex:department ?department ;
            ex:salary ?salary .
}
GROUP BY ?department
HAVING (COUNT(?person) > 10 && AVG(?salary) > 50000)

# HAVING with bound variables
SELECT ?person (COUNT(?friend) AS ?friendCount) WHERE {
    ?person foaf:knows ?friend ;
            foaf:age ?age .
}
GROUP BY ?person
HAVING (COUNT(?friend) > 3 && ?age < 30)

Property Paths

Basic Property Paths

PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX ex: <http://example.org/>

# Zero or more (*)
SELECT ?person ?ancestor WHERE {
    ?person ex:hasParent* ?ancestor .
}

# One or more (+)
SELECT ?person ?descendant WHERE {
    ?person ex:hasChild+ ?descendant .
}

# Zero or one (?)
SELECT ?person ?contact WHERE {
    ?person ex:primaryContact? ?contact .
}

# Exact number {n}
SELECT ?person ?relative WHERE {
    ?person ex:hasParent{2} ?relative .  # Grandparents
}

# Range {n,m}
SELECT ?person ?ancestor WHERE {
    ?person ex:hasParent{1,3} ?ancestor .  # Parents, grandparents, great-grandparents
}

# At least n {n,}
SELECT ?person ?ancestor WHERE {
    ?person ex:hasParent{2,} ?ancestor .  # Grandparents and beyond
}

Path Alternatives

PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX vcard: <http://www.w3.org/2006/vcard/ns#>

# Alternative paths (|)
SELECT ?person ?name WHERE {
    ?person foaf:name|vcard:fn ?name .
}

# Complex alternatives
SELECT ?person ?contact WHERE {
    ?person foaf:mbox|foaf:phone|vcard:email ?contact .
}

# Alternatives with paths
SELECT ?person ?relative WHERE {
    ?person (ex:hasParent|ex:hasChild)+ ?relative .
}

Path Sequences

PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX ex: <http://example.org/>

# Sequence (/)
SELECT ?person ?friendOfFriend WHERE {
    ?person foaf:knows/foaf:knows ?friendOfFriend .
    FILTER (?person != ?friendOfFriend)
}

# Longer sequences
SELECT ?person ?greatGrandparent WHERE {
    ?person ex:hasParent/ex:hasParent/ex:hasParent ?greatGrandparent .
}

# Mixed sequences and alternatives
SELECT ?person ?contact WHERE {
    ?person foaf:knows/foaf:mbox|foaf:phone ?contact .
}

# Sequences with repetition
SELECT ?person ?colleague WHERE {
    ?person (ex:worksFor/ex:employs)+ ?colleague .
}

Inverse Paths

PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX ex: <http://example.org/>

# Inverse path (^)
SELECT ?child ?parent WHERE {
    ?child ^ex:hasChild ?parent .
    # Equivalent to: ?parent ex:hasChild ?child .
}

# Inverse with repetition
SELECT ?person ?descendant WHERE {
    ?person ^ex:hasParent+ ?descendant .
}

# Complex inverse paths
SELECT ?person ?manager WHERE {
    ?person ^ex:manages/ex:worksFor ?manager .
}

Negated Property Paths

PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX ex: <http://example.org/>

# Negated property set (!)
SELECT ?s ?o WHERE {
    ?s !rdf:type ?o .  # Any property except rdf:type
}

# Negated alternative
SELECT ?person ?value WHERE {
    ?person !(foaf:name|foaf:mbox) ?value .
}

# Negated in path
SELECT ?person ?other WHERE {
    ?person !foaf:knows/foaf:name ?other .
}

Complex Property Path Examples

PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX ex: <http://example.org/>

# Social network exploration
SELECT ?person ?distance ?connection WHERE {
    ex:Alice (foaf:knows+) ?connection .
    BIND (strlen(?path) AS ?distance)
}

# Organizational hierarchy
SELECT ?employee ?boss WHERE {
    ?employee ex:reportsTo+ ?boss .
    ?boss ex:title "CEO" .
}

# Family tree
SELECT ?person ?bloodRelative WHERE {
    ?person (ex:hasParent|^ex:hasParent|ex:hasSibling)+ ?bloodRelative .
    FILTER (?person != ?bloodRelative)
}

# Transitive closure with cycle detection
SELECT DISTINCT ?start ?end WHERE {
    VALUES ?start { ex:NodeA }
    ?start ex:linksTo+ ?end .
}

# Path with intermediate nodes
SELECT ?person ?friend ?friendOfFriend ?skill WHERE {
    ?person foaf:knows ?friend .
    ?friend foaf:knows ?friendOfFriend .
    ?friendOfFriend ex:hasSkill ?skill .
    FILTER (?person != ?friendOfFriend)
}

Federated Queries

SERVICE Keyword

PREFIX foaf: <http://xmlns.com/foaf/0.1/>

# Basic federated query
SELECT ?person ?name WHERE {
    # Local query
    ?person a foaf:Person .

    # Remote query to DBpedia
    SERVICE <http://dbpedia.org/sparql> {
        ?person foaf:name ?name .
    }
}

# SERVICE with OPTIONAL
SELECT ?person ?dbpediaInfo WHERE {
    ?person a foaf:Person .

    OPTIONAL {
        SERVICE <http://dbpedia.org/sparql> {
            ?person rdfs:label ?dbpediaInfo .
            FILTER (lang(?dbpediaInfo) = "en")
        }
    }
}

# Multiple SERVICE endpoints
SELECT ?person ?name ?bio WHERE {
    ?person a foaf:Person .

    SERVICE <http://dbpedia.org/sparql> {
        ?person foaf:name ?name .
    }

    SERVICE <http://example.org/sparql> {
        ?person ex:biography ?bio .
    }
}

SERVICE SILENT

PREFIX foaf: <http://xmlns.com/foaf/0.1/>

# Silently fail if remote endpoint unavailable
SELECT ?person ?name WHERE {
    ?person a foaf:Person .

    SERVICE SILENT <http://dbpedia.org/sparql> {
        ?person foaf:name ?name .
    }
}

# Fallback pattern with multiple services
SELECT ?person ?info WHERE {
    ?person a foaf:Person .

    {
        SERVICE SILENT <http://primary.example.org/sparql> {
            ?person ex:info ?info .
        }
    }
    UNION
    {
        SERVICE SILENT <http://backup.example.org/sparql> {
            ?person ex:info ?info .
        }
    }
}

Wikidata Examples

PREFIX wd: <http://www.wikidata.org/entity/>
PREFIX wdt: <http://www.wikidata.org/prop/direct/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>

# Query Wikidata for cities
SELECT ?city ?cityLabel ?population WHERE {
    SERVICE <https://query.wikidata.org/sparql> {
        ?city wdt:P31 wd:Q515 ;        # Instance of city
              wdt:P1082 ?population ;   # Population
              rdfs:label ?cityLabel .
        FILTER (lang(?cityLabel) = "en")
        FILTER (?population > 1000000)
    }
}
ORDER BY DESC(?population)
LIMIT 10

# Query for programming languages
SELECT ?lang ?langLabel ?influenced WHERE {
    SERVICE <https://query.wikidata.org/sparql> {
        ?lang wdt:P31 wd:Q9143 ;           # Instance of programming language
              wdt:P737 ?influenced ;        # Influenced by
              rdfs:label ?langLabel .
        FILTER (lang(?langLabel) = "en")
    }
}

DBpedia Examples

PREFIX dbo: <http://dbpedia.org/ontology/>
PREFIX dbr: <http://dbpedia.org/resource/>

# Query DBpedia for movies
SELECT ?movie ?title ?director WHERE {
    SERVICE <http://dbpedia.org/sparql> {
        ?movie a dbo:Film ;
               dbo:director ?director ;
               rdfs:label ?title .
        FILTER (lang(?title) = "en")
        FILTER (regex(?title, "Star Wars"))
    }
}

# Query for geographical data
SELECT ?country ?capital ?population WHERE {
    SERVICE <http://dbpedia.org/sparql> {
        ?country a dbo:Country ;
                 dbo:capital ?capital ;
                 dbo:populationTotal ?population .
        FILTER (?population > 50000000)
    }
}
ORDER BY DESC(?population)

Common Ontologies

RDF Schema (RDFS)

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>

# Class hierarchy
SELECT ?class ?superClass WHERE {
    ?class rdfs:subClassOf ?superClass .
}

# Property hierarchy
SELECT ?property ?superProperty WHERE {
    ?property rdfs:subPropertyOf ?superProperty .
}

# Labels and comments
SELECT ?resource ?label ?comment WHERE {
    ?resource rdfs:label ?label ;
              rdfs:comment ?comment .
    FILTER (lang(?label) = "en")
}

# Domain and range
SELECT ?property ?domain ?range WHERE {
    ?property rdfs:domain ?domain ;
              rdfs:range ?range .
}

# Type inference
SELECT ?resource ?type WHERE {
    ?resource a ?directType .
    ?directType rdfs:subClassOf* ?type .
}

FOAF (Friend of a Friend)

PREFIX foaf: <http://xmlns.com/foaf/0.1/>

# Person information
SELECT ?person ?name ?email ?homepage WHERE {
    ?person a foaf:Person ;
            foaf:name ?name .
    OPTIONAL { ?person foaf:mbox ?email }
    OPTIONAL { ?person foaf:homepage ?homepage }
}

# Social network
SELECT ?person ?friend ?friendName WHERE {
    ?person foaf:name "Alice" ;
            foaf:knows ?friend .
    ?friend foaf:name ?friendName .
}

# Organizations
SELECT ?org ?name ?member WHERE {
    ?org a foaf:Organization ;
         foaf:name ?name ;
         foaf:member ?member .
}

# Accounts
SELECT ?person ?account ?accountName WHERE {
    ?person foaf:account ?account .
    ?account foaf:accountName ?accountName .
}

Dublin Core

PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX dcterms: <http://purl.org/dc/terms/>

# Metadata queries
SELECT ?resource ?title ?creator ?date WHERE {
    ?resource dc:title ?title ;
              dc:creator ?creator ;
              dc:date ?date .
}

# Subject classification
SELECT ?resource ?subject WHERE {
    ?resource dc:subject ?subject .
}

# Rights and license
SELECT ?resource ?rights ?license WHERE {
    ?resource dcterms:rights ?rights ;
              dcterms:license ?license .
}

SKOS (Simple Knowledge Organization System)

PREFIX skos: <http://www.w3.org/2004/02/skos/core#>

# Concept schemes
SELECT ?concept ?prefLabel ?scheme WHERE {
    ?concept a skos:Concept ;
             skos:prefLabel ?prefLabel ;
             skos:inScheme ?scheme .
    FILTER (lang(?prefLabel) = "en")
}

# Hierarchical relations
SELECT ?broader ?concept ?narrower WHERE {
    ?concept skos:broader ?broader ;
             skos:narrower ?narrower .
}

# Related concepts
SELECT ?concept ?related WHERE {
    ?concept skos:related ?related .
}

# Alternative labels
SELECT ?concept ?prefLabel ?altLabel WHERE {
    ?concept skos:prefLabel ?prefLabel ;
             skos:altLabel ?altLabel .
    FILTER (lang(?prefLabel) = "en")
}

OWL (Web Ontology Language)

PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

# OWL classes
SELECT ?class WHERE {
    ?class a owl:Class .
}

# Equivalent classes
SELECT ?class1 ?class2 WHERE {
    ?class1 owl:equivalentClass ?class2 .
}

# Disjoint classes
SELECT ?class1 ?class2 WHERE {
    ?class1 owl:disjointWith ?class2 .
}

# Object properties
SELECT ?property ?domain ?range WHERE {
    ?property a owl:ObjectProperty ;
              rdfs:domain ?domain ;
              rdfs:range ?range .
}

# Datatype properties
SELECT ?property ?domain ?range WHERE {
    ?property a owl:DatatypeProperty ;
              rdfs:domain ?domain ;
              rdfs:range ?range .
}

# Property characteristics
SELECT ?property ?characteristic WHERE {
    ?property a owl:ObjectProperty .
    {
        ?property a owl:SymmetricProperty .
        BIND ("Symmetric" AS ?characteristic)
    }
    UNION
    {
        ?property a owl:TransitiveProperty .
        BIND ("Transitive" AS ?characteristic)
    }
    UNION
    {
        ?property a owl:FunctionalProperty .
        BIND ("Functional" AS ?characteristic)
    }
}

# Restrictions
SELECT ?class ?property ?restriction WHERE {
    ?class rdfs:subClassOf ?restriction .
    ?restriction a owl:Restriction ;
                 owl:onProperty ?property .
}

Schema.org

PREFIX schema: <http://schema.org/>

# Organizations
SELECT ?org ?name ?url WHERE {
    ?org a schema:Organization ;
         schema:name ?name ;
         schema:url ?url .
}

# People
SELECT ?person ?name ?email ?jobTitle WHERE {
    ?person a schema:Person ;
            schema:name ?name ;
            schema:email ?email ;
            schema:jobTitle ?jobTitle .
}

# Events
SELECT ?event ?name ?startDate ?location WHERE {
    ?event a schema:Event ;
           schema:name ?name ;
           schema:startDate ?startDate ;
           schema:location ?location .
}

# Products
SELECT ?product ?name ?price ?brand WHERE {
    ?product a schema:Product ;
             schema:name ?name ;
             schema:offers/schema:price ?price ;
             schema:brand ?brand .
}

Best Practices

Query Optimization

# ✓ Good: Specific patterns first
SELECT ?person ?name WHERE {
    ?person foaf:name "Alice" .      # Specific
    ?person foaf:knows ?friend .     # More general
    ?friend foaf:name ?name .
}

# ✗ Bad: General patterns first
SELECT ?person ?name WHERE {
    ?person foaf:knows ?friend .     # Too general first
    ?friend foaf:name ?name .
    ?person foaf:name "Alice" .      # Specific last
}

# ✓ Good: Use FILTER efficiently
SELECT ?person ?age WHERE {
    ?person foaf:age ?age .
    FILTER (?age >= 18 && ?age < 65)
}

# ✗ Bad: Multiple separate FILTERs
SELECT ?person ?age WHERE {
    ?person foaf:age ?age .
    FILTER (?age >= 18)
    FILTER (?age < 65)
}

# ✓ Good: Use property paths when appropriate
SELECT ?person ?ancestor WHERE {
    ?person ex:hasParent+ ?ancestor .
}

# ✗ Bad: Manual recursion (verbose and limited)
SELECT ?person ?ancestor WHERE {
    {
        ?person ex:hasParent ?ancestor .
    }
    UNION
    {
        ?person ex:hasParent/ex:hasParent ?ancestor .
    }
    UNION
    {
        ?person ex:hasParent/ex:hasParent/ex:hasParent ?ancestor .
    }
}

Using Prefixes Effectively

# ✓ Good: Define all prefixes at the start
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX ex: <http://example.org/>

SELECT ?person ?name WHERE {
    ?person a foaf:Person ;
            foaf:name ?name .
}

# ✗ Bad: Full URIs in query
SELECT ?person ?name WHERE {
    ?person a <http://xmlns.com/foaf/0.1/Person> ;
            <http://xmlns.com/foaf/0.1/name> ?name .
}

Handling Optional Data

# ✓ Good: Use OPTIONAL for truly optional data
SELECT ?person ?name ?email WHERE {
    ?person foaf:name ?name .
    OPTIONAL {
        ?person foaf:mbox ?email .
    }
}

# ✓ Good: Provide defaults with COALESCE
SELECT ?person ?contact WHERE {
    ?person foaf:name ?name .
    OPTIONAL { ?person foaf:mbox ?email }
    OPTIONAL { ?person foaf:phone ?phone }
    BIND (COALESCE(?email, ?phone, "No contact") AS ?contact)
}

# ✓ Good: Check for bound variables
SELECT ?person ?name WHERE {
    ?person foaf:name ?name .
    OPTIONAL { ?person foaf:mbox ?email }
    FILTER (bound(?email))
}

Type Safety and Validation

# ✓ Good: Validate data types
SELECT ?person ?age WHERE {
    ?person foaf:age ?age .
    FILTER (datatype(?age) = xsd:integer)
    FILTER (?age >= 0 && ?age < 150)
}

# ✓ Good: Handle language tags
SELECT ?resource ?label WHERE {
    ?resource rdfs:label ?label .
    FILTER (lang(?label) = "en" || lang(?label) = "")
}

# ✓ Good: Validate URIs
SELECT ?person ?homepage WHERE {
    ?person foaf:homepage ?homepage .
    FILTER (isURI(?homepage))
    FILTER (strstarts(str(?homepage), "https://"))
}

Reusable Query Patterns

# Pattern: Pagination
SELECT ?person ?name WHERE {
    ?person foaf:name ?name .
}
ORDER BY ?name
LIMIT 20
OFFSET 0  # Increment by 20 for each page

# Pattern: Search with ranking
SELECT ?resource ?label (SUM(?score) AS ?totalScore) WHERE {
    {
        ?resource rdfs:label ?label .
        FILTER (contains(lcase(?label), "search term"))
        BIND (10 AS ?score)
    }
    UNION
    {
        ?resource rdfs:comment ?comment .
        FILTER (contains(lcase(?comment), "search term"))
        BIND (5 AS ?score)
    }
}
GROUP BY ?resource ?label
ORDER BY DESC(?totalScore)

# Pattern: Existence check
SELECT ?resource WHERE {
    ?resource a ex:RequiredType .
    FILTER EXISTS { ?resource ex:requiredProperty ?value }
    FILTER NOT EXISTS { ?resource ex:forbiddenProperty ?any }
}

# Pattern: Hierarchical query with depth limit
SELECT ?parent ?child ?depth WHERE {
    VALUES ?root { ex:StartNode }
    ?root ex:hasChild{1,3} ?child .
    ?child ^ex:hasChild{1,3} ?parent .
    BIND (/* calculate depth */ AS ?depth)
}

Error Prevention

# ✓ Good: Avoid division by zero
SELECT ?person ((?total / ?count) AS ?average) WHERE {
    ?person ex:total ?total ;
            ex:count ?count .
    FILTER (?count != 0)
}

# ✓ Good: Handle missing language tags
SELECT ?resource ?label WHERE {
    ?resource rdfs:label ?label .
    FILTER (
        !bound(lang(?label)) ||
        lang(?label) = "" ||
        lang(?label) = "en"
    )
}

# ✓ Good: Safe string operations
SELECT ?person ?name ?initial WHERE {
    ?person foaf:name ?name .
    FILTER (strlen(?name) > 0)
    BIND (substr(?name, 1, 1) AS ?initial)
}

Performance Considerations

# ✓ Good: Limit early when exploring
SELECT ?s ?p ?o WHERE {
    ?s ?p ?o .
}
LIMIT 100

# ✓ Good: Use COUNT efficiently
SELECT (COUNT(*) AS ?count) WHERE {
    ?s a foaf:Person .
}

# ✓ Good: Avoid expensive operations in FILTER
SELECT ?person ?name WHERE {
    ?person foaf:name ?name .
    ?person foaf:age ?age .
}
HAVING (?age > 18)  # Better in HAVING for grouped results

# ✗ Bad: Expensive regex in FILTER
SELECT ?person ?name WHERE {
    ?person foaf:name ?name .
    FILTER (regex(?name, "^[A-Z][a-z]+\\s[A-Z][a-z]+$"))
}
# Better: Check format on application side if possible

This skill provides foundational SPARQL patterns for querying RDF data and working with knowledge graphs. These patterns cover standard query operations, graph patterns, aggregations, property paths, federated queries, and common semantic web ontologies. Use this as a reference for SPARQL development and semantic web applications.