SPARQL 1.2 질의 언어

W3C 작업 초안

이 문서에 대한 자세한 정보
이 버전:
https://www.w3.org/TR/2026/WD-sparql12-query-20260625/
최신 공개 버전:
https://www.w3.org/TR/sparql12-query/
최신 편집자 초안:
https://w3c.github.io/sparql-query/spec/
이력:
https://www.w3.org/standards/history/sparql12-query/
커밋 이력
테스트 모음:
https://w3c.github.io/rdf-tests/
최신 권고안:
https://www.w3.org/TR/2013/REC-sparql11-query-20130321
편집자:
Olaf Hartig
Andy Seaborne
Ruben Taelman
Gregory Williams
Thomas Pellissier Tanon
이전 편집자:
Steve Harris
Andy Seaborne
Eric Prud'hommeaux
피드백:
GitHub w3c/sparql-query (pull requests, 새 이슈, 열려 있는 이슈)
public-rdf-star-wg@w3.org 제목 줄 [sparql12-query] … 메시지 주제 … 포함 (아카이브)

초록

RDF는 웹에서 정보를 표현하기 위한 방향성이 있고 레이블이 지정된 그래프 데이터 모델입니다. 이 명세는 RDF를 위한 SPARQL 질의 언어의 구문과 의미론을 정의합니다. SPARQL은 데이터가 RDF로 기본 저장되어 있든 미들웨어를 통해 RDF로 간주되든, 다양한 데이터 소스 전반에 걸친 질의를 표현하는 데 사용할 수 있습니다. SPARQL은 필수 및 선택적 그래프 패턴과 그 결합 및 분리를 질의하는 기능을 포함합니다. SPARQL은 또한 집계, 하위 질의, 부정, 표현식에 의한 값 생성, 확장 가능한 값 테스트, 그리고 소스 RDF 그래프로 질의를 제한하는 기능을 지원합니다. SPARQL 질의의 결과는 결과 집합 또는 RDF 그래프일 수 있습니다.

이 문서의 상태

이 절은 이 문서가 발행된 시점의 상태를 설명합니다. 현재 W3C 발행물과 이 기술 보고서의 최신 개정판 목록은 W3C 표준 및 초안 색인에서 찾을 수 있습니다.

이 명세는 형식 및 정오표 명세 갱신의 일부로 RDF Star 작업 그룹에서 발행합니다.

이 문서는 RDF & SPARQL 작업 그룹에서 권고안 트랙을 사용하여 작업 초안으로 발행했습니다.

작업 초안으로 발행되었다고 해서 W3C 및 그 회원의 승인을 의미하지는 않습니다.

이 문서는 초안 문서이며 언제든지 다른 문서로 갱신, 대체 또는 폐기될 수 있습니다. 이 문서를 진행 중인 작업 이외의 것으로 인용하는 것은 적절하지 않습니다. 향후 이 예정된 권고안의 갱신에는 새 기능이 포함될 수 있습니다.

이 문서는 W3C 특허 정책에 따라 운영되는 그룹이 작성했습니다. W3C는 이 그룹의 산출물과 관련하여 이루어진 특허 공개의 공개 목록을 유지하며, 해당 페이지에는 특허 공개 지침도 포함되어 있습니다. 개인이 자신이 믿기에 필수 청구항을 포함하는 특허에 대해 실제로 알고 있는 경우, 그 개인은 W3C 특허 정책 6절에 따라 정보를 공개해야 합니다.

이 문서는 2025년 8월 18일 W3C 프로세스 문서의 적용을 받습니다.

1. 서론

RDF는 웹에서 정보를 표현하기 위한 방향성이 있고 레이블이 지정된 그래프 데이터 모델입니다. RDF는 무엇보다도 개인 정보, 소셜 네트워크, 디지털 산출물에 대한 메타데이터를 표현하고, 서로 다른 정보 소스 간의 통합 수단을 제공하는 데 자주 사용됩니다. 이 명세는 RDF를 위한 SPARQL 질의 언어의 구문과 의미론을 정의합니다.

RDF용 SPARQL 질의 언어는 [RDF-DAWG-UC]의 RDF Data Access Working Group, [SPARQL-FEATURES]의 SPARQL 1.1 Working Group, 그리고 RDF-star Working Group이 식별한 사용 사례와 요구사항을 충족하도록 설계되었습니다.

1.1 문서 개요

절 제목에 달리 명시되지 않는 한, 이 문서의 모든 절과 부록은 규범적입니다.

이 문서의 이 절인 1절은 SPARQL 질의 언어 명세를 소개합니다. 이 명세 문서의 구성과 명세 전반에서 사용되는 규약을 제시합니다.

명세의 2절은 일련의 예제 질의와 질의 결과를 통해 SPARQL 질의 언어 자체를 소개합니다. 3절은 질의 결과에 나타나는 RDF 용어에 대한 제약을 표현하는 SPARQL의 능력을 보여 주는 더 많은 예제로 SPARQL 질의 언어 소개를 이어갑니다.

4절은 SPARQL 질의 언어의 구문 세부 사항을 제시합니다. 이는 언어의 전체 문법에 대한 동반 설명이며, 문법적 구성 요소가 IRI, 빈 노드, 리터럴 및 변수를 어떻게 표현하는지를 정의합니다. 또한 4절은 더 장황한 표현을 위한 구문적 설탕 역할을 하는 여러 문법적 구성 요소의 의미도 정의합니다.

5절은 더 복잡한 SPARQL 질의 패턴을 구성하는 빌딩 블록인 기본 그래프 패턴과 그룹 그래프 패턴을 소개합니다. 6, 7, 8절은 SPARQL 그래프 패턴을 더 큰 그래프 패턴으로 결합하는 구성 요소를 제시합니다. 특히 6절은 질의의 일부를 선택적으로 만드는 기능을 소개하고, 7절은 대안 그래프 패턴의 분리를 표현하는 기능을 소개하며, 8절은 정보의 부재를 테스트하는 패턴을 소개합니다.

9절은 그래프 패턴 일치에 속성 경로를 추가하여, 질의의 간결한 표현과 그래프에서 임의 길이 경로를 일치시키는 기능을 제공합니다.

10절은 SPARQL에서 가능한 할당 형식을 설명합니다.

11절은 결과를 그룹화하고 집계하는 메커니즘을 소개하며, 이는 12절에서 설명하는 하위 질의로 포함될 수 있습니다.

13절은 질의의 일부를 특정 소스 그래프로 제한하는 기능을 소개합니다. 또한 13절은 질의를 위한 소스 그래프를 정의하는 SPARQL의 메커니즘도 제시합니다.

14절은 별도의 문서인 SPARQL 1.1 Federated Query를 참조합니다.

15절은 해의 시퀀스를 정렬, 슬라이싱, 투영, 제한하고 중복을 제거함으로써 질의의 해에 영향을 주는 구성 요소를 정의합니다.

16절은 서로 다른 형식으로 결과를 산출하는 네 가지 유형의 SPARQL 질의를 정의합니다.

17절은 SPARQL의 확장 가능한 값 테스트 및 표현식 프레임워크를 정의합니다. 질의 결과에 나타나는 값을 제약하고, 질의가 반환할 새 값을 계산하는 데 사용할 수 있는 함수와 연산자를 제시합니다.

18절은 SPARQL 그래프 패턴과 해 수정자의 평가에 대한 형식적 정의입니다.

19절은 EBNF 표기법으로 표현된 문법에 따라 주어진 SPARQL 질의와 SPARQL 1.1 Update 언어 구문의 규범적 정의를 포함합니다.

1.2 문서 규약

1.2.1 네임스페이스

이 문서에서 예제는 달리 명시되지 않는 한 다음 네임스페이스 접두사 정의를 가정합니다.

접두사 IRI
rdf: http://www.w3.org/1999/02/22-rdf-syntax-ns#
rdfs: http://www.w3.org/2000/01/rdf-schema#
xsd: http://www.w3.org/2001/XMLSchema#
fn: http://www.w3.org/2005/xpath-functions#

1.2.2 데이터 설명

이 문서는 각 트리플을 명시적으로 보여 주기 위해 RDF 1.1 Turtle [TURTLE] 데이터 형식을 사용합니다. Turtle은 IRI를 접두사로 축약할 수 있게 합니다.

PREFIX dc:   <http://purl.org/dc/elements/1.1/>
PREFIX :     <http://example.org/book/>

:book1  dc:title  "SPARQL Tutorial" .

1.2.3 결과 설명

결과 집합은 표 형식으로 예시됩니다.

x y z
"Alice" <http://example/a>      

'바인딩'은 (변수, RDF 용어) 쌍입니다. 이 결과 집합에는 세 개의 변수가 있습니다. x, yz(열 머리글로 표시됨). 각 해는 표 본문의 한 행으로 표시됩니다.  여기에는 하나의 해가 있으며, 변수 x"Alice"에 바인딩되고, 변수 y<http://example/a>에 바인딩되며, 변수 z는 RDF 용어에 바인딩되지 않습니다. 변수는 해에서 반드시 바인딩될 필요가 없습니다.

1.2.4 용어

SPARQL 언어에는 IRI가 포함됩니다. SPARQL 질의의 모든 IRI는 절대 IRI라는 점에 유의하십시오. 이들은 조각 식별자 [RFC3987] 3.1절을 포함할 수도 있고 포함하지 않을 수도 있습니다. IRI에는 URI [RFC3986]와 URL이 포함됩니다. SPARQL 구문의 축약 형식(상대 IRI와 접두 이름)은 절대 IRI를 생성하도록 해석됩니다.

다음 용어는 RDF 1.2 Concepts and Abstract Data Model [RDF12-CONCEPTS]에서 정의되며 SPARQL에서 사용됩니다.

빈 노드 식별자는 SPARQL과 RDF 구체 직렬화의 일부입니다. 이 문서에서는 구문 형식 "_:abc"가 사용되며, 여기서 빈 노드 식별자abc입니다. 그리고 "_:"는 식별자가 있는 빈 노드를 도입하는 데 사용되는 Turtle 및 SPARQL 구문입니다.

2. 단순 질의 만들기 (정보 제공)

대부분의 SPARQL 질의 형식은 기본 그래프 패턴이라고 하는 트리플 패턴의 집합을 포함합니다. 트리플 패턴은 RDF 트리플과 비슷하지만 주어, 술어 및 목적어 각각이 변수가 될 수 있다는 점이 다릅니다. 기본 그래프 패턴은 해당 하위 그래프의 RDF 용어가 변수에 대입될 수 있고 그 결과가 그 하위 그래프와 동등한 RDF 그래프가 될 때 RDF 데이터의 하위 그래프와 일치합니다.

2.1 단순 질의 작성

아래 예제는 주어진 데이터 그래프에서 책의 제목을 찾는 SPARQL 질의를 보여 줍니다. 질의는 두 부분으로 구성됩니다. SELECT 절은 질의 결과에 나타날 변수를 식별하고, WHERE 절은 데이터 그래프와 일치시킬 기본 그래프 패턴을 제공합니다. 이 예제의 기본 그래프 패턴은 목적어 위치에 하나의 변수(?title)가 있는 단일 트리플 패턴으로 구성됩니다.

데이터:

<http://example.org/book/book1> <http://purl.org/dc/elements/1.1/title> "SPARQL Tutorial" .

질의:

SELECT ?title
WHERE
{
    <http://example.org/book/book1> <http://purl.org/dc/elements/1.1/title> ?title .
}

위 데이터에 대해 이 질의는 하나의 해를 가집니다.

질의 결과:

title
"SPARQL Tutorial"

2.2 여러 일치

질의의 결과는 해 시퀀스이며, 질의의 그래프 패턴이 데이터와 일치하는 방식에 해당합니다. 질의에는 0개, 1개 또는 여러 개의 해가 있을 수 있습니다.

데이터:

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

_:a  foaf:name   "Johnny Lee Outlaw" .
_:a  foaf:mbox   <mailto:jlow@example.com> .
_:b  foaf:name   "Peter Goodguy" .
_:b  foaf:mbox   <mailto:peter@example.org> .
_:c  foaf:mbox   <mailto:carol@example.org> .

질의:

PREFIX foaf:   <http://xmlns.com/foaf/0.1/>
SELECT ?name ?mbox
WHERE
{ ?x foaf:name ?name .
  ?x foaf:mbox ?mbox }

질의 결과:

name mbox
"Johnny Lee Outlaw" <mailto:jlow@example.com>
"Peter Goodguy" <mailto:peter@example.org>

각 해는 선택된 변수가 RDF 용어에 바인딩되어 질의 패턴이 데이터와 일치할 수 있는 하나의 방식을 제공합니다. 결과 집합은 가능한 모든 해를 제공합니다. 위 예제에서는 제공된 데이터의 다음 두 부분집합이 두 개의 일치를 제공했습니다.

_:a foaf:name  "Johnny Lee Outlaw" .
_:a foaf:box   <mailto:jlow@example.com> .
_:b foaf:name  "Peter Goodguy" .
_:b foaf:box   <mailto:peter@example.org> .

이는 기본 그래프 패턴 일치입니다. 질의 패턴에서 사용되는 모든 변수는 모든 해에서 반드시 바인딩되어야 합니다.

2.3 RDF 리터럴 일치

아래 데이터에는 세 개의 RDF 리터럴이 포함되어 있습니다.

PREFIX dt:   <http://example.org/datatype#>
PREFIX ns:   <http://example.org/ns#>
PREFIX :     <http://example.org/ns#>
PREFIX xsd:  <http://www.w3.org/2001/XMLSchema#>

:x   ns:p     "cat"@en .
:y   ns:p     "42"^^xsd:integer .
:z   ns:p     "abc"^^dt:specialDatatype .

Turtle에서 "cat"@en은 어휘 형식 "cat"과 언어 태그 "en"을 가진 RDF 리터럴이고, "42"^^xsd:integer는 데이터 타입 http://www.w3.org/2001/XMLSchema#integer를 가진 리터럴이며, "abc"^^dt:specialDatatype는 데이터 타입 http://example.org/datatype#specialDatatype를 가진 리터럴입니다.

이 RDF 데이터는 2.3.1–2.3.3절의 질의 예제에 대한 데이터 그래프입니다.

2.3.1 언어 태그가 있는 리터럴 일치

SPARQL의 언어 태그는 Tags for Identifying Languages [BCP47]에 정의된 대로 @와 언어 태그를 사용하여 표현됩니다.

다음 질의는 "cat""cat"@en과 동일한 RDF 리터럴이 아니므로 해가 없습니다.

SELECT ?v WHERE { ?v ?p "cat" }
   v    

하지만 아래 질의는 언어 태그가 지정되어 주어진 데이터와 일치하므로 변수 v:x에 바인딩되는 해를 찾습니다.

SELECT ?v WHERE { ?v ?p "cat"@en }
v
<http://example.org/ns#x>

SPARQL은 또한 주어진 기본 방향의 일치를 지원한다. Turtle에서와 같이, 이는 언어 태그 뒤에 작성되며, 예를 들어 @en--ltr와 같다. 기본 방향은 ltr 또는 rtl 중 하나로 제한된다. 언어 태그와 달리, 이는 항상 소문자이다.

2.3.2 숫자 타입 리터럴 일치

SPARQL 질의의 정수는 데이터 타입이 xsd:integer인 RDF 리터럴을 나타냅니다. 예를 들어 42는 다음의 축약 형식입니다.  "42"^^<http://www.w3.org/2001/XMLSchema#integer>.

다음 질의의 패턴은 변수 v:y에 바인딩되는 해를 가집니다.

SELECT ?v WHERE { ?v ?p 42 }
v
<http://example.org/ns#y>

4.1.2절xsd:floatxsd:double에 대한 SPARQL 축약 형식을 정의합니다.

2.3.3 임의 데이터 타입 리터럴 일치

다음 질의는 변수 v:z에 바인딩되는 해를 가집니다. 질의 처리기는 데이터 타입의 값 공간에 있는 값에 대해 어떤 이해도 가질 필요가 없습니다. 어휘 형식과 데이터 타입 IRI가 모두 일치하기 때문에 리터럴이 일치합니다.

SELECT ?v WHERE { ?v ?p "abc"^^<http://example.org/datatype#specialDatatype> }
v
<http://example.org/ns#z>

2.4 질의 결과의 빈 노드 식별자

질의 결과에는 빈 노드가 포함될 수 있습니다. 이 문서의 예제 결과 집합에서 빈 노드는 "_:" 뒤에 빈 노드 식별자가 오는 형식으로 작성됩니다.

빈 노드 식별자는 결과 집합("SPARQL Query Results XML Format (Second Edition)" 및 "SPARQL 1.1 Query Results JSON Format" 참조) 또는 CONSTRUCT 질의 형식의 경우 결과 그래프를 범위로 합니다. 결과 집합 내에서 같은 식별자를 사용하면 같은 빈 노드를 나타냅니다.

데이터:
PREFIX foaf:  <http://xmlns.com/foaf/0.1/>

_:a  foaf:name   "Alice" .
_:b  foaf:name   "Bob" .
질의:
PREFIX foaf:   <http://xmlns.com/foaf/0.1/>
SELECT ?x ?name
WHERE  { ?x foaf:name ?name }
x name
_:c "Alice"
_:d "Bob"

위 결과는 서로 다른 빈 노드 식별자를 사용하여 동일하게 제공될 수도 있습니다. 결과의 빈 노드 식별자는 해에 있는 RDF 용어가 같은지 또는 다른지만 나타내기 때문입니다.

x name
_:r "Alice"
_:s "Bob"

이 두 결과는 같은 정보를 가집니다. 질의와 일치하는 데 사용된 빈 노드는 두 해에서 서로 다릅니다. 결과 집합의 빈 노드 식별자 _:a와 데이터 구문에서 사용된 빈 노드 식별자 사이에는 어떤 관계도 있을 필요가 없습니다.

애플리케이션 작성자는 질의의 빈 노드 식별자가 데이터의 특정 빈 노드를 참조한다고 기대해서는 안 됩니다.

2.5 표현식으로 값 만들기

SPARQL 1.2는 복잡한 표현식에서 값을 만들 수 있게 합니다. 아래 질의는 CONCAT 함수를 사용하여 FOAF 데이터에서 이름과 성을 연결한 다음, SELECT 절의 표현식을 사용해 값을 할당하고, 또한 BIND 형식을 사용해 값을 할당하는 방법을 보여 줍니다.

데이터:
PREFIX foaf:  <http://xmlns.com/foaf/0.1/>
            
_:a  foaf:givenName   "John" .
_:a  foaf:surname  "Doe" .
질의:
PREFIX foaf:   <http://xmlns.com/foaf/0.1/>
SELECT ( CONCAT(?G, " ", ?S) AS ?name )
WHERE  { ?P foaf:givenName ?G ; foaf:surname ?S }
질의:
PREFIX foaf:   <http://xmlns.com/foaf/0.1/>
SELECT ?name
WHERE  { 
    ?P foaf:givenName ?G ; 
       foaf:surname ?S 
    BIND(CONCAT(?G, " ", ?S) AS ?name)
}
name
"John Doe"

2.6 RDF 그래프 구축

SPARQL에는 여러 질의 형식이 있습니다. SELECT 질의 형식은 변수 바인딩을 반환합니다. CONSTRUCT 질의 형식은 RDF 그래프를 반환합니다. 그래프는 질의의 그래프 패턴 일치 결과를 바탕으로 RDF 트리플을 생성하는 데 사용되는 템플릿을 기반으로 구축됩니다.

데이터:

PREFIX org:    <http://example.com/ns#>

_:a  org:employeeName   "Alice" .
_:a  org:employeeId     12345 .

_:b  org:employeeName   "Bob" .
_:b  org:employeeId     67890 .

질의:

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

CONSTRUCT { ?x foaf:name ?name }
WHERE  { ?x org:employeeName ?name }

결과:

PREFIX foaf: <http://xmlns.com/foaf/0.1/>
                
_:x foaf:name "Alice" .
_:y foaf:name "Bob" .

이는 다음과 같이 RDF/XML로 직렬화할 수 있습니다.

<rdf:RDF
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:foaf="http://xmlns.com/foaf/0.1/" >

  <rdf:Description>
    <foaf:name>Alice</foaf:name>
  </rdf:Description>
  <rdf:Description>
    <foaf:name>Bob</foaf:name>
  </rdf:Description>
</rdf:RDF>

3. RDF 용어 제약(정보 제공)

그래프 패턴 일치는 해 시퀀스를 생성하며, 각 해는 변수에서 RDF 용어로의 바인딩 집합을 가집니다. SPARQL FILTER는 필터 표현식이 TRUE로 평가되는 해로 제한합니다.

이 절은 SPARQL FILTER에 대한 비공식적인 소개를 제공합니다. 그 의미론은 표현식과 값 테스트 절에서 정의되며, 거기에는 포괄적인 함수 라이브러리가 있습니다. 이 절의 예제는 하나의 입력 그래프를 공유합니다.

데이터:
PREFIX dc:   <http://purl.org/dc/elements/1.1/>
PREFIX :     <http://example.org/book/>
PREFIX ns:   <http://example.org/ns#>

:book1  dc:title  "SPARQL Tutorial" .
:book1  ns:price  42 .
:book2  dc:title  "The Semantic Web" .
:book2  ns:price  23 .

3.1 문자열 값 제한

regex와 같은 SPARQL FILTER 함수는 RDF 리터럴을 테스트할 수 있습니다. regex문자열 리터럴에만 일치합니다. regexstr 함수를 사용하여 다른 리터럴의 어휘 형식과 일치시키는 데 사용할 수 있습니다.

질의:

PREFIX  dc:  <http://purl.org/dc/elements/1.1/>
SELECT  ?title
WHERE   { 
    ?x dc:title ?title
    FILTER regex(?title, "^SPARQL") 
}

질의 결과:

title
"SPARQL Tutorial"

정규식 일치는 "i" 플래그로 대소문자를 구분하지 않도록 만들 수 있습니다.

질의:

PREFIX  dc:  <http://purl.org/dc/elements/1.1/>
SELECT  ?title
WHERE   { 
    ?x dc:title ?title
    FILTER regex(?title, "web", "i" ) 
}

질의 결과:

title
"The Semantic Web"

정규식 언어는 XQuery 및 XPath Functions and Operators에서 정의되며 XML Schema 정규식을 기반으로 합니다.

3.2 숫자 값 제한

SPARQL FILTER는 산술 표현식에 대해 제한할 수 있습니다.

질의:

PREFIX  dc:  <http://purl.org/dc/elements/1.1/>
PREFIX  ns:  <http://example.org/ns#>

SELECT  ?title ?price
WHERE   {
    ?x ns:price ?price .
    FILTER (?price < 30.5)
    ?x dc:title ?title . 
}

질의 결과:

title price
"The Semantic Web" 23

price 변수를 제약함으로써 :book2만 질의와 일치합니다. 필터 조건이 요구하듯이 :book230.5보다 작은 가격을 가지기 때문입니다.

3.3 기타 용어 제약

숫자 타입 외에도 SPARQL은 xsd:string, xsd:booleanxsd:dateTime 타입을 지원합니다 (피연산자 데이터 타입 참조). 연산자 매핑 절은 연산자를 설명하고, 함수 정의 절은 RDF 용어에 적용할 수 있는 함수를 설명합니다.

4. SPARQL 구문

이 절은 SPARQL에서 RDF 용어트리플 패턴에 사용하는 구문을 다룹니다. 전체 문법은 19절에 제시되어 있습니다.

4.1 RDF 용어 구문

4.1.1 IRI 구문

iri 생성식은 IRI [RFC3987]의 집합을 나타냅니다. IRI는 URI [RFC3986]의 일반화이며 URI 및 URL과 완전히 호환됩니다. PrefixedName 생성식은 접두 이름을 나타냅니다. 접두 이름에서 IRI로의 매핑은 아래에 설명되어 있습니다. IRI 참조(상대 또는 절대 IRI)는 IRIREF 생성식으로 나타내며, 여기서 '<' 및 '>' 구분자는 IRI 참조의 일부를 이루지 않습니다. 상대 IRI는 [RFC3987]의 IRI References and IRIs에 대한 2.2절 ABNF의 irelative-ref 참조와 일치하며, 아래에 설명된 대로 IRI로 해석됩니다.

4.1.1.1 접두 이름

PREFIX 키워드는 접두사 레이블을 IRI와 연결합니다. 접두 이름은 콜론 ":"으로 구분되는 접두사 레이블과 로컬 부분입니다. 접두 이름은 접두사와 연결된 IRI와 로컬 부분을 연결하여 IRI에 매핑됩니다. 접두사 레이블 또는 로컬 부분은 비어 있을 수 있습니다. SPARQL 로컬 이름은 앞에 숫자를 허용하지만 XML 로컬 이름은 그렇지 않다는 점에 유의하십시오. SPARQL 로컬 이름은 또한 백슬래시 문자 이스케이프를 통해 IRI에서 허용되는 비영숫자 문자도 허용합니다 (예: ns:id\=123). SPARQL 로컬 이름CURIE보다 더 많은 구문적 제한을 가집니다.

4.1.1.2 상대 IRI

상대 IRI는 Uniform Resource Identifier (URI): Generic Syntax [RFC3986]에 따라 5.2절의 기본 알고리즘만을 사용하여 기준 IRI와 결합됩니다. 구문 기반 정규화나 스킴 기반 정규화([RFC3986]의 6.2.2절 및 6.2.3절에 설명됨)는 수행되지 않습니다. IRI 참조에서 추가로 허용되는 문자는 Internationalized Resource Identifiers (IRIs) [RFC3987]의 6.5절에 따라 URI 참조의 예약되지 않은 문자가 처리되는 방식과 동일하게 처리됩니다.

BASE 키워드는 [RFC3986] 5.1.1절 "Base URI Embedded in Content"에 따라 상대 IRI를 해석하는 데 사용되는 기준 IRI를 정의합니다. 5.1.2절 "Base URI from the Encapsulating Entity"는 기준 IRI가 xml:base 지시자가 있는 SOAP 봉투나 Content-Location 헤더가 있는 mime multipart 문서와 같은 캡슐화 문서에서 올 수 있는 방법을 정의합니다. 5.1.3절 Base "URI from the Retrieval URI"에서 식별되는 "Retrieval URI"는 특정 SPARQL 질의를 가져온 URL입니다. 위의 어느 것도 기준 URI를 지정하지 않으면 기본 기준 URI(5.1.4절 "Default Base URI")가 사용됩니다.

다음 조각들은 동일한 IRI를 작성하는 몇 가지 서로 다른 방법입니다.

<http://example.org/book/book1>
BASE <http://example.org/book/>
<book1>
PREFIX book: <http://example.org/book/>
book:book1

4.1.2 리터럴 구문

리터럴의 일반 구문은 문자열(큰따옴표 "..." 또는 작은따옴표 '...'로 둘러싸임)에 선택적 언어 태그(@로 도입됨)나 선택적 데이터 타입 IRI 또는 접두 이름(^^로 도입됨)이 붙는 형태입니다.

편의를 위해 정수는 직접 작성할 수 있으며(따옴표와 명시적 데이터 타입 IRI 없이) 데이터 타입이 xsd:integer인 리터럴로 해석됩니다. 숫자 안에 '.'이 있지만 지수가 없는 십진수는 xsd:decimal로 해석됩니다. 지수가 있는 숫자는 xsd:double로 해석됩니다. xsd:boolean 타입의 값도 true 또는 false로 작성할 수 있습니다.

그 자체가 따옴표를 포함하거나 길고 줄바꿈 문자를 포함하는 리터럴 값을 작성하기 쉽게 하기 위해, SPARQL은 리터럴을 세 개의 작은따옴표 또는 큰따옴표로 둘러싸는 추가 인용 구문을 제공합니다.

SPARQL의 리터럴 구문 예는 다음과 같습니다.

  • "chat"
  • 'chat'@fr 언어 태그 "fr" 포함
  • "xyz"^^<http://example.org/ns/userDatatype>
  • "abc"^^appNS:appDataType
  • '''The librarian said, "Perhaps you would enjoy 'War and Peace'."'''
  • 1, 이는 "1"^^xsd:integer와 같습니다
  • 1.3, 이는 "1.3"^^xsd:decimal과 같습니다
  • 1.300, 이는 "1.300"^^xsd:decimal과 같습니다
  • 1.0e6, 이는 "1.0e6"^^xsd:double과 같습니다
  • true, 이는 "true"^^xsd:boolean과 같습니다
  • false, 이는 "false"^^xsd:boolean과 같습니다

생성식 INTEGER, DECIMAL, DOUBLE 또는 BooleanLiteral 중 하나와 일치하는 토큰은 해당 토큰의 어휘 값과 대응하는 데이터 타입 (xsd:integer, xsd:decimal, xsd:double 또는 xsd:boolean)을 가진 리터럴과 동등합니다.

4.1.3 질의 변수 구문

질의 변수는 "?" 또는 "$"의 사용으로 표시됩니다. "?" 또는 "$"는 변수 이름의 일부가 아닙니다. 질의에서 $abc?abc는 같은 변수를 식별합니다. 변수에 사용할 수 있는 가능한 이름SPARQL 문법에 제시되어 있습니다.

4.1.4 빈 노드 구문

그래프 패턴의 빈 노드는 질의되는 데이터의 특정 빈 노드에 대한 참조가 아니라 변수처럼 동작합니다. 빈 노드는 "_:abc"와 같은 식별자 형식이나 "[]" 또는 "[...]"를 사용하는 축약 형식으로 표시됩니다.

빈 노드 식별자는 식별자 "abc"를 가진 빈 노드에 대해 "_:abc"로 작성됩니다. 동일한 빈 노드 식별자는 같은 질의 안의 서로 다른 두 기본 그래프 패턴에서 사용할 수 없습니다.

질의 구문에서 한 곳에만 사용되는 빈 노드는 []로 표시할 수 있습니다. 고유한 빈 노드가 트리플 패턴을 형성하는 데 사용됩니다.

[:p :v] 구성은 포함된 술어-객체 쌍의 주어로 고유한 빈 노드를 가진 트리플 패턴을 만드는 데 사용할 수 있습니다.

다음 두 형식은

[ :p "v" ] .
[] :p "v" .

고유한 빈 노드(여기서는 "_:b57"로 예시됨)를 할당하며, 둘 다 다음과 같이 작성한 것과 동등합니다.

_:b57 :p "v" .

할당된 빈 노드는 추가 트리플 패턴의 주어나 객체로 사용할 수 있습니다. 예를 들어 주어로는 다음과 같습니다.

[ :p "v" ] :q "w" .

이는 다음 두 트리플과 동등합니다.

_:b57 :p "v" .
_:b57 :q "w" .

객체로는 다음과 같습니다.

:x :q [ :p "v" ] .

이는 다음 두 트리플과 동등합니다.

:x  :q _:b57 .
_:b57 :p "v" .

축약된 빈 노드 구문은 공통 주어공통 술어에 대한 다른 축약과 결합할 수 있습니다.

[ foaf:name  ?name ;
  foaf:mbox  <mailto:alice@example.org> ]

이는 대신 빈 노드 식별자를 사용하여 다음 기본 그래프 패턴을 작성한 것과 같습니다.

_:b18  foaf:name  ?name .
_:b18  foaf:mbox  <mailto:alice@example.org> .

4.2 트리플 패턴 구문

트리플 패턴은 주어, 술어 및 객체로 작성됩니다. 일부 일반적인 트리플 패턴 구성 요소를 작성하는 축약 방법이 있습니다.

다음 예제들은 동일한 질의를 표현합니다.

PREFIX  dc: <http://purl.org/dc/elements/1.1/>
SELECT  ?title
WHERE   { <http://example.org/book/book1> dc:title ?title }
PREFIX  dc: <http://purl.org/dc/elements/1.1/>
PREFIX  : <http://example.org/book/>

SELECT  $title
WHERE   { :book1  dc:title  $title }
BASE    <http://example.org/book/>
PREFIX  dc: <http://purl.org/dc/elements/1.1/>

SELECT  $title
WHERE   { <book1>  dc:title  ?title }

4.2.1 술어-객체 목록

공통 주어를 가진 트리플 패턴은 ";" 표기법을 사용하여 주어를 한 번만 작성하고 둘 이상의 트리플 패턴에 사용되도록 작성할 수 있습니다.

?x  foaf:name  ?name ;
foaf:mbox  ?mbox .

이는 다음 트리플 패턴을 작성한 것과 같습니다.

?x  foaf:name  ?name .
?x  foaf:mbox  ?mbox .

4.2.2 객체 목록

트리플 패턴이 주어와 술어를 모두 공유하는 경우, 객체는 ","로 구분할 수 있습니다.

?x foaf:nick  "Alice" , "Alice_" .

이는 다음 트리플 패턴을 작성한 것과 같습니다.

?x  foaf:nick  "Alice" .
?x  foaf:nick  "Alice_" .

객체 목록은 술어-객체 목록과 결합할 수 있습니다.

?x  foaf:name ?name ; foaf:nick  "Alice" , "Alice_" .

이는 다음과 동등합니다.

?x  foaf:name  ?name .
?x  foaf:nick  "Alice" .
?x  foaf:nick  "Alice_" .

4.2.3 RDF 컬렉션

RDF 컬렉션은 구문 "(element1 element2 ...)"를 사용하여 트리플 패턴 안에 작성할 수 있습니다. 형식 "()"는 IRI http://www.w3.org/1999/02/22-rdf-syntax-ns#nil의 대안입니다. (1 ?x 3 4)와 같이 컬렉션 요소와 함께 사용되면, 컬렉션을 위한 빈 노드가 있는 트리플 패턴이 할당됩니다. 컬렉션의 머리에 있는 빈 노드는 다른 트리플 패턴에서 주어나 객체로 사용할 수 있습니다. 컬렉션 구문이 할당한 빈 노드는 질의의 다른 곳에는 나타나지 않습니다.

(1 ?x 3 4) :p "w" .

이는 (b0, b1, b2b3가 질의의 다른 곳에 나타나지 않는다는 점에 유의하면) 다음에 대한 구문적 설탕입니다.

_:b0  rdf:first  1 ;
      rdf:rest   _:b1 .
_:b1  rdf:first  ?x ;
      rdf:rest   _:b2 .
_:b2  rdf:first  3 ;
      rdf:rest   _:b3 .
_:b3  rdf:first  4 ;
      rdf:rest   rdf:nil .
_:b0  :p         "w" .

RDF 컬렉션은 중첩될 수 있으며 다른 구문 형식을 포함할 수 있습니다.

(1 [:p :q] ( 2 ) ) .

이는 다음에 대한 구문적 설탕입니다.

_:b0  rdf:first  1 ;
      rdf:rest   _:b1 .
_:b1  rdf:first  _:b2 .
_:b2  :p         :q .
_:b1  rdf:rest   _:b3 .
_:b3  rdf:first  _:b4 .
_:b4  rdf:first  2 ;
      rdf:rest   rdf:nil .
_:b3  rdf:rest   rdf:nil .

4.2.4 rdf:type

키워드 "a"는 트리플 패턴에서 술어로 사용할 수 있으며 IRI  http://www.w3.org/1999/02/22-rdf-syntax-ns#type의 대안입니다. 이 키워드는 대소문자를 구분합니다.

?x  a  :Class1 .
[ a :appClass ] :p "v" .

이는 다음에 대한 구문적 설탕입니다.

?x    rdf:type  :Class1 .
_:b0  rdf:type  :appClass .
_:b0  :p        "v" .

4.3 버전 선언

SPARQL의 언어 진화에 대응하기 위해 VERSION 지시자를 사용할 수 있습니다. 트리플 용어 또는 트리플 용어에 대한 함수와 같은 새 기능이 포함된 SPARQL 질의를 작성할 때, 작성자는 이 지시자를 포함하고 포함된 기능을 처리하는 데 필요한 버전을 나타내는 버전 레이블을 뒤따르게 함으로써 새 구문 형식의 사용을 선언할 수 있습니다.

버전 레이블은 다음 절에서 정의됩니다. 처리기는 인식할 수 없는 레이블을 오류 또는 경고로 처리할 수 있습니다.

VERSION "1.2"
PREFIX : <http://example/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

SELECT ?s ?date {
    ?s ?p ?o .
    BIND( <<( ?s ?p ?o )>> AS ?tt )
    :myreifier rdf:reifies ?tt .
    :myreifier :tripleAdded ?date .
}

SPARQL 1.2 프로토콜버전 알림미디어 타입version 매개변수를 사용해 제공한다. 이는 VERSION 지시어가 없는 경우 고려된다.

4.3.1 버전 레이블

SPARQL 버전 레이블은 SPARQL 질의의 구문 및 의미론 준수를 식별하는 문자열이다.

참고

SPARQL의 버전 레이블 문자열이 RDF에서 정의한 버전 레이블과 동일하더라도, 그 의미는 다르다. 구체적으로, SPARQL 버전 레이블은 SPARQL 구문 및 의미론을 가리키는 반면, RDF 버전 레이블은 RDF 구문 및 의미론을 가리킨다.

SPARQL 버전 레이블
버전 레이블 구문 의미론
"1.2" SPARQL 1.2 질의 또는 갱신 구문 SPARQL 1.2 질의 언어, SPARQL 1.2 Update
"1.2-basic" 트리플 용어가 없고, 주어나 객체 위치에 트리플 패턴을 가진 트리플 패턴도 없는 SPARQL 1.2 질의 또는 갱신 구문 SPARQL 1.2 질의 언어, SPARQL 1.2 Update
"1.1" 버전 지시자의 사용을 제외한 SPARQL 1.1 질의 또는 갱신 구문 SPARQL 1.1 질의 언어, SPARQL 1.1 Update

질의가 버전 "1.1"을 준수하면 버전 "1.2-basic"도 준수하며, 질의가 버전 "1.2-basic"을 준수하면 버전 "1.2"도 준수합니다.

"1.1"은 허용 가능한 버전 레이블이지만, VERSION 지시자에서 사용하는 것은 권장되지 않습니다. SPARQL 1.1 파서가 불필요하게 실패하게 만들 수 있기 때문입니다.

5. 그래프 패턴

SPARQL은 그래프 패턴 일치를 중심으로 합니다. 더 복잡한 그래프 패턴은 더 작은 패턴을 다양한 방식으로 결합하여 형성할 수 있습니다.

이 절에서는 결합으로 패턴을 결합하는 두 가지 형식, 즉 트리플 패턴을 결합하는 기본 그래프 패턴과 다른 모든 그래프 패턴을 결합하는 그룹 그래프 패턴을 설명합니다.

질의에서 가장 바깥쪽 그래프 패턴을 질의 패턴이라고 합니다. 이는 문법적으로 다음의 GroupGraphPattern으로 식별됩니다.

[17]   WhereClause   ::=   'WHERE'? GroupGraphPattern

5.1 기본 그래프 패턴

기본 그래프 패턴은 트리플 패턴의 집합입니다. SPARQL 그래프 패턴 일치는 기본 그래프 패턴을 일치시킨 결과를 결합하는 방식으로 정의됩니다.

선택적 필터가 있는 트리플 패턴의 시퀀스는 하나의 기본 그래프 패턴을 구성합니다. 다른 모든 그래프 패턴은 기본 그래프 패턴을 종료합니다.

5.1.1 빈 노드 식별자

_:abc 형식의 빈 노드를 사용할 때, 빈 노드의 식별자는 기본 그래프 패턴을 범위로 합니다. 빈 노드 식별자는 어떤 질의에서도 하나의 기본 그래프 패턴에서만 사용할 수 있습니다.

5.1.2 기본 그래프 패턴 일치 확장

SPARQL은 단순 함의에 대해 정의된 하위 그래프 일치를 사용하여 기본 그래프 패턴을 평가합니다. SPARQL은 아래에 설명된 대로 특정 조건이 주어지면 다른 형태의 함의로 확장될 수 있습니다. 문서 SPARQL 1.1 Entailment Regimes는 여러 특정 함의 체계를 설명합니다.

5.2 그룹 그래프 패턴

SPARQL 질의 문자열에서 그룹 그래프 패턴은 중괄호 {}로 구분됩니다. 예를 들어 이 질의의 질의 패턴은 하나의 기본 그래프 패턴으로 이루어진 그룹 그래프 패턴입니다.

PREFIX foaf:    <http://xmlns.com/foaf/0.1/>
SELECT ?name ?mbox
WHERE  {
    ?x foaf:name ?name .
    ?x foaf:mbox ?mbox .
}
트리플 패턴을 두 개의 기본 그래프 패턴으로 그룹화한 질의에서도 같은 해를 얻을 수 있습니다. 예를 들어 아래 질의는 구조가 다르지만 이전 질의와 같은 해를 산출합니다.
PREFIX foaf:    <http://xmlns.com/foaf/0.1/>
SELECT ?name ?mbox
WHERE  { 
   { ?x foaf:name ?name . }
   { ?x foaf:mbox ?mbox . }
}

5.2.1 빈 그룹 패턴

그룹 패턴:

{ }

은 어떤 그래프(빈 그래프 포함)와도 일치하며, 어떤 변수도 바인딩하지 않는 하나의 해를 가집니다. 예를 들어:

SELECT ?x
WHERE {}

는 변수 x가 바인딩되지 않은 하나의 해와 일치합니다.

5.2.2 필터의 범위

FILTER 키워드로 표현되는 제약은 필터가 나타나는 전체 그룹에 대한 해의 제한입니다. 다음 패턴들은 모두 동일한 해를 가집니다.

{  ?x foaf:name ?name .
   ?x foaf:mbox ?mbox .
   FILTER regex(?name, "Smith")
}
{  FILTER regex(?name, "Smith")
   ?x foaf:name ?name .
   ?x foaf:mbox ?mbox .
}
{  ?x foaf:name ?name .
   FILTER regex(?name, "Smith")
   ?x foaf:mbox ?mbox .
}

5.2.3 그룹 그래프 패턴 예제

{ ?x foaf:name ?name .
  ?x foaf:mbox ?mbox .
}

은 하나의 기본 그래프 패턴으로 이루어진 그룹이며, 그 기본 그래프 패턴은 두 개의 트리플 패턴으로 구성됩니다.

{
  ?x foaf:name ?name . FILTER regex(?name, "Smith")
  ?x foaf:mbox ?mbox .
}

은 하나의 기본 그래프 패턴과 하나의 필터로 이루어진 그룹이며, 그 기본 그래프 패턴은 두 개의 트리플 패턴으로 구성됩니다. 필터는 기본 그래프 패턴을 두 개의 기본 그래프 패턴으로 나누지 않습니다.

{
  ?x foaf:name ?name .
  {}
  ?x foaf:mbox ?mbox .
}

은 세 요소로 이루어진 그룹입니다. 하나의 트리플 패턴으로 이루어진 기본 그래프 패턴, 빈 그룹, 그리고 하나의 트리플 패턴으로 이루어진 또 다른 기본 그래프 패턴입니다.

6. 선택적 값 포함

기본 그래프 패턴은 전체 질의 패턴이 일치해야만 해가 있는 질의를 애플리케이션이 만들 수 있게 합니다. 적어도 하나의 기본 그래프 패턴을 가진 그룹 그래프 패턴만 포함하는 질의의 모든 해에서, 모든 변수는 해 안의 RDF 용어에 바인딩됩니다. 그러나 모든 RDF 그래프에서 규칙적이고 완전한 구조를 가정할 수는 없습니다. 정보를 사용할 수 있는 경우 그 정보를 해에 추가할 수 있지만, 질의 패턴의 일부가 일치하지 않는다고 해서 해를 거부하지 않는 질의를 사용할 수 있으면 유용합니다. 선택적 일치는 이러한 기능을 제공합니다. 선택적 부분이 일치하지 않으면 바인딩을 만들지 않지만 해를 제거하지는 않습니다.

6.1 선택적 패턴 일치

그래프 패턴의 선택적 부분은 그래프 패턴에 OPTIONAL 키워드를 적용하여 구문적으로 지정할 수 있습니다.

pattern OPTIONAL { pattern }

구문 형식:

{ OPTIONAL { pattern } }

은 다음과 동등합니다.

{ { } OPTIONAL { pattern } }

OPTIONAL 키워드는 왼쪽 결합입니다.

pattern OPTIONAL { pattern } OPTIONAL { pattern }

은 다음과 같습니다.

{ pattern OPTIONAL { pattern } } OPTIONAL { pattern }

선택적 일치에서는 선택적 그래프 패턴이 그래프와 일치하여 하나 이상의 해에 바인딩을 정의하고 추가하거나, 또는 추가 바인딩을 추가하지 않고 해를 그대로 둡니다.

데이터:

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

_:a  rdf:type        foaf:Person .
_:a  foaf:name       "Alice" .
_:a  foaf:mbox       <mailto:alice@example.com> .
_:a  foaf:mbox       <mailto:alice@work.example> .

_:b  rdf:type        foaf:Person .
_:b  foaf:name       "Bob" .
질의:
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name ?mbox
WHERE  {
    ?x foaf:name  ?name .
    OPTIONAL { ?x  foaf:mbox  ?mbox }
}

위 데이터를 사용하면 질의 결과는 다음과 같습니다.

name mbox
"Alice" <mailto:alice@example.com>
"Alice" <mailto:alice@work.example>
"Bob"

이름이 "Bob"인 해에는 mbox 값이 없습니다.

이 질의는 데이터에 있는 사람들의 이름을 찾습니다. 술어가 mbox이고 주어가 같은 트리플이 있으면, 해는 그 트리플의 객체도 포함합니다. 이 예제에서는 질의의 선택적 일치 부분에 단일 트리플 패턴만 주어져 있지만, 일반적으로 선택적 부분은 어떤 그래프 패턴도 될 수 있습니다. 선택적 그래프 패턴이 질의 해에 영향을 주려면 전체 선택적 그래프 패턴이 일치해야 합니다.

6.2 선택적 패턴 일치의 제약

선택적 그래프 패턴 안에 제약을 줄 수 있습니다. 예를 들면 다음과 같습니다.

PREFIX dc:   <http://purl.org/dc/elements/1.1/>
PREFIX :     <http://example.org/book/>
PREFIX ns:   <http://example.org/ns#>

:book1  dc:title  "SPARQL Tutorial" .
:book1  ns:price  42 .
:book2  dc:title  "The Semantic Web" .
:book2  ns:price  23 .
PREFIX  dc:  <http://purl.org/dc/elements/1.1/>
PREFIX  ns:  <http://example.org/ns#>
SELECT  ?title ?price
WHERE   { 
    ?x dc:title ?title .
    OPTIONAL { ?x ns:price ?price . FILTER (?price < 30) }
}
title price
"SPARQL Tutorial"
"The Semantic Web" 23

제목이 "SPARQL Tutorial"인 책에 가격이 나타나지 않는 이유는 선택적 그래프 패턴이 변수 "price"를 포함하는 해로 이어지지 않았기 때문입니다.

6.3 여러 선택적 그래프 패턴

그래프 패턴은 재귀적으로 정의됩니다. 그래프 패턴은 0개 이상의 선택적 그래프 패턴을 가질 수 있으며, 질의 패턴의 어떤 부분도 선택적 부분을 가질 수 있습니다. 이 예제에는 두 개의 선택적 그래프 패턴이 있습니다.

데이터:
PREFIX foaf:       <http://xmlns.com/foaf/0.1/>

_:a  foaf:name       "Alice" .
_:a  foaf:homepage   <http://work.example.org/alice/> .

_:b  foaf:name       "Bob" .
_:b  foaf:mbox       <mailto:bob@work.example> .
질의:
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name ?mbox ?hpage
WHERE  {
    ?x foaf:name  ?name .
    OPTIONAL { ?x foaf:mbox ?mbox } .
    OPTIONAL { ?x foaf:homepage ?hpage }
}

질의 결과:

name mbox hpage
"Alice" <http://work.example.org/alice/>
"Bob" <mailto:bob@work.example>

7. 대안 일치

SPARQL은 여러 대안 그래프 패턴 중 하나가 일치할 수 있도록 그래프 패턴을 결합하는 수단을 제공합니다. 대안 중 둘 이상이 일치하면 가능한 모든 패턴 해를 찾습니다.

패턴 대안은 UNION 키워드로 구문적으로 지정됩니다.

데이터:
PREFIX dc10:  <http://purl.org/dc/elements/1.0/>
PREFIX dc11:  <http://purl.org/dc/elements/1.1/>

_:a  dc10:title     "SPARQL Query Language Tutorial" .
_:a  dc10:creator   "Alice" .

_:b  dc11:title     "SPARQL Protocol Tutorial" .
_:b  dc11:creator   "Bob" .

_:c  dc10:title     "SPARQL" .
_:c  dc11:title     "SPARQL (updated)" .
질의:
PREFIX dc10:  <http://purl.org/dc/elements/1.0/>
PREFIX dc11:  <http://purl.org/dc/elements/1.1/>

SELECT ?title
WHERE  { { ?book dc10:title  ?title } UNION { ?book dc11:title  ?title } }

질의 결과:

title
"SPARQL Protocol Tutorial"
"SPARQL"
"SPARQL (updated)"
"SPARQL Query Language Tutorial"

이 질의는 제목이 버전 1.0 또는 버전 1.1의 Dublin Core 속성을 사용하여 기록되었는지와 관계없이, 데이터에 있는 책의 제목을 찾습니다. 정보가 정확히 어떻게 기록되었는지 확인하려면 질의가 두 대안에 서로 다른 변수를 사용할 수 있습니다.

PREFIX dc10:  <http://purl.org/dc/elements/1.0/>
PREFIX dc11:  <http://purl.org/dc/elements/1.1/>

SELECT ?x ?y
WHERE  { { ?book dc10:title ?x } UNION { ?book dc11:title  ?y } }
x y
"SPARQL (updated)"
"SPARQL Protocol Tutorial"
"SPARQL"
"SPARQL Query Language Tutorial"

이는 UNION의 왼쪽 분기에서 온 해에는 변수 x가 바인딩되고, 오른쪽 분기에서 온 해에는 y가 바인딩된 결과를 반환합니다. UNION 패턴의 어느 부분도 일치하지 않으면 그래프 패턴은 일치하지 않습니다.

UNION 패턴은 그래프 패턴을 결합합니다. 각 대안 가능성은 둘 이상의 트리플 패턴을 포함할 수 있습니다.

PREFIX dc10:  <http://purl.org/dc/elements/1.0/>
PREFIX dc11:  <http://purl.org/dc/elements/1.1/>

SELECT ?title ?author
WHERE {
    { ?book dc10:title ?title .  ?book dc10:creator ?author }
      UNION
    { ?book dc11:title ?title .  ?book dc11:creator ?author }
}
title author
"SPARQL Query Language Tutorial" "Alice"
"SPARQL Protocol Tutorial" "Bob"

이 질의는 책이 동일한 버전의 Dublin Core에서 온 title 술어와 creator 술어를 모두 가진 경우에만 일치합니다.

8. 부정

SPARQL 질의 언어는 두 가지 방식의 부정을 포함합니다. 하나는 필터링되는 질의 해의 문맥에서 그래프 패턴이 일치하는지 여부에 따라 결과를 필터링하는 방식이고, 다른 하나는 다른 패턴과 관련된 해를 제거하는 방식입니다.

8.1 그래프 패턴을 사용한 필터링

질의 해의 필터링은 FILTER 표현식 안에서 NOT EXISTSEXISTS를 사용하여 수행됩니다. 필터 범위 규칙은 필터가 나타나는 전체 그룹에 적용된다는 점에 유의하십시오.

8.1.1 패턴 부재 테스트

NOT EXISTS 필터 표현식은 필터가 발생하는 그룹 그래프 패턴의 변수 값이 주어졌을 때, 그래프 패턴이 데이터셋과 일치하지 않는지를 테스트합니다. 이는 추가 바인딩을 생성하지 않습니다.

데이터:

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

:alice  rdf:type   foaf:Person .
:alice  foaf:name  "Alice" .
:bob    rdf:type   foaf:Person .

질의:

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

SELECT ?person
WHERE 
{
    ?person rdf:type  foaf:Person .
    FILTER NOT EXISTS { ?person foaf:name ?name }
}

질의 결과:

person
<http://example/bob>

8.1.2 패턴 존재 테스트

필터 표현식 EXISTS도 제공됩니다. 이는 패턴을 데이터에서 찾을 수 있는지를 테스트하며, 추가 바인딩을 생성하지 않습니다.

질의:

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

SELECT ?person
WHERE {
    ?person rdf:type  foaf:Person .
    FILTER EXISTS { ?person foaf:name ?name }
}

질의 결과:

person
<http://example/alice>

8.2 가능한 해 제거

SPARQL에서 제공되는 다른 방식의 부정은 MINUS입니다. 이는 두 인자를 모두 평가한 다음, 왼쪽의 해 중 오른쪽의 해와 호환되지 않는 해를 계산합니다.

데이터:
PREFIX :       <http://example/>
PREFIX foaf:   <http://xmlns.com/foaf/0.1/>

:alice  foaf:givenName "Alice" ;
        foaf:familyName "Smith" .

:bob    foaf:givenName "Bob" ;
        foaf:familyName "Jones" .

:carol  foaf:givenName "Carol" ;
        foaf:familyName "Smith" .
질의:
PREFIX :       <http://example/>
PREFIX foaf:   <http://xmlns.com/foaf/0.1/>

SELECT DISTINCT ?s
WHERE {
    ?s ?p ?o .
    MINUS {
        ?s foaf:givenName "Bob" .
    }
}

결과:

s
<http://example/carol>
<http://example/alice>

8.3 NOT EXISTS와 MINUS의 관계 및 차이

NOT EXISTSMINUS는 부정을 생각하는 두 가지 방식을 나타냅니다. 하나는 질의 패턴에서 이미 결정된 바인딩이 주어졌을 때 패턴이 데이터에 존재하는지 테스트하는 방식이고, 다른 하나는 두 패턴의 평가를 바탕으로 일치를 제거하는 방식입니다. 어떤 경우에는 서로 다른 답을 생성할 수 있습니다.

8.3.1 예: 변수 공유

PREFIX : <http://example/>
:a :b :c .
SELECT * { 
    ?s ?p ?o
    FILTER NOT EXISTS { ?x ?y ?z }
}

는 해가 없는 결과 집합으로 평가됩니다. { ?x ?y ?z }가 임의의 ?s ?p ?o가 주어져도 일치하므로, NOT EXISTS { ?x ?y ?z }가 모든 해를 제거하기 때문입니다.

s p o

반면 MINUS에서는 첫 번째 부분 (?s ?p ?o)과 두 번째 부분(?x ?y ?z) 사이에 공유 변수가 없으므로 어떤 바인딩도 제거되지 않습니다.

SELECT * { 
    ?s ?p ?o 
    MINUS 
    { ?x ?y ?z }
}

결과:

s p o
<http://example/a> <http://example/b> <http://example/c>

8.3.2 예: 고정 패턴

또 다른 경우는 예제에 구체적인 패턴(변수 없음)이 있는 경우입니다.

PREFIX : <http://example/>
SELECT * {  
    ?s ?p ?o 
    FILTER NOT EXISTS { :a :b :c }
}

는 질의 해가 없는 결과 집합으로 평가됩니다.

결과:
s p o

반면

PREFIX : <http://example/>
SELECT * 
{ 
    ?s ?p ?o 
    MINUS { :a :b :c }
}

는 하나의 질의 해가 있는 결과 집합으로 평가됩니다.

결과:

s p o
<http://example/a> <http://example/b> <http://example/c>

이는 바인딩의 일치가 없으므로 해가 제거되지 않기 때문입니다.

8.3.3 예: 내부 FILTER

필터에서는 그룹의 변수가 범위 안에 있기 때문에 차이도 발생합니다. 이 예제에서 NOT EXISTS 안의 FILTER는 고려 중인 해의 ?n 값에 접근할 수 있습니다.

PREFIX : <http://example.com/>
:a :p 1 .
:a :q 1 .
:a :q 2 .

:b :p 3.0 .
:b :q 4.0 .
:b :q 5.0 .

FILTER NOT EXISTS를 사용할 때 테스트는 ?x :p ?n의 각 가능한 해에 대해 이루어집니다.

PREFIX : <http://example.com/>
SELECT * WHERE {
    ?x :p ?n
    FILTER NOT EXISTS {
        ?x :q ?m .
        FILTER(?n = ?m)
    }
}
x n
<http://example.com/b> 3.0

반면 MINUS에서는 패턴 안의 FILTER가 ?n 값을 갖지 않으며 항상 바인딩되지 않습니다.

PREFIX : <http://example/>
SELECT * WHERE {
    ?x :p ?n
    MINUS {
        ?x :q ?m .
        FILTER(?n = ?m)
    }
}
x n
<http://example.com/b> 3.0
<http://example.com/a> 1

9. 속성 경로

속성 경로는 두 그래프 노드 사이에서 그래프를 통과하는 가능한 경로입니다. 사소한 경우는 길이가 정확히 1인 속성 경로이며, 이는 트리플 패턴입니다. 경로의 양끝은 RDF 용어 또는 변수가 될 수 있습니다. 변수는 경로 자체의 일부로는 사용할 수 없고, 양끝에만 사용할 수 있습니다.

속성 경로는 일부 SPARQL 기본 그래프 패턴을 더 간결하게 표현할 수 있게 하며, 또한 임의 길이 경로로 두 리소스의 연결성을 일치시키는 기능을 추가합니다.

9.1 속성 경로 구문

아래 설명에서 iri전체로 작성되거나 접두 이름으로 축약된 IRI 또는 키워드 a입니다. elt는 경로 요소이며, 그 자체가 경로 구성 요소로 이루어질 수 있습니다.

구문 형식 속성 경로 표현식 이름 일치 대상
iri PredicatePath IRI. 길이 1의 경로.
^elt InversePath 역방향 경로(객체에서 주어로).
elt1 / elt2 SequencePath elt1 뒤에 elt2가 오는 시퀀스 경로.
elt1 | elt2 AlternativePath elt1 또는 elt2의 대안 경로(모든 가능성을 시도함).
elt* ZeroOrMorePath elt의 0회 이상 일치로 경로의 주어와 객체를 연결하는 경로.
elt+ OneOrMorePath elt의 1회 이상 일치로 경로의 주어와 객체를 연결하는 경로.
elt? ZeroOrOnePath elt의 0회 또는 1회 일치로 경로의 주어와 객체를 연결하는 경로.
!iri or !(iri1| ...|irin) NegatedPropertySet 부정된 속성 집합. irii 중 하나가 아닌 IRI. !iri!(iri)의 축약입니다.
!^iri or !(^iri1| ...|^irin) NegatedPropertySet 제외되는 일치가 역방향 경로를 기반으로 하는 부정된 속성 집합.
즉, 역방향 경로로서 iri1...irin 중 하나가 아님. !^iri!(^iri)의 축약입니다.
!(iri1| ...|irij|^irij+1| ...|^irin) NegatedPropertySet 부정된 속성 집합 안의 순방향 및 역방향 속성의 조합.
(elt)   그룹 경로 elt. 괄호는 우선순위를 제어합니다.

부정된 속성 집합에서 IRI와 역방향 IRI의 순서는 중요하지 않으며, 서로 섞인 순서로 나타날 수 있습니다.

구문 형식의 우선순위는 높은 것부터 낮은 것까지 다음과 같습니다.

우선순위는 그룹 내에서 왼쪽에서 오른쪽입니다.

9.2 예제

대안: 하나 또는 두 가능성 모두와 일치

{ :book1 dc:title|rdfs:label ?displayString }

이는 다음과 같이 작성할 수도 있습니다.

{ 
   :book1 <http://purl.org/dc/elements/1.1/title> | <http://www.w3.org/2000/01/rdf-schema#label> ?displayString
}

시퀀스: Alice가 아는 사람들의 이름 찾기.

{
    ?x foaf:mbox <mailto:alice@example> .
    ?x foaf:knows/foaf:name ?name .
}

시퀀스: "foaf:knows" 링크 두 단계 떨어진 사람들의 이름 찾기.

{ 
    ?x foaf:mbox <mailto:alice@example> .
    ?x foaf:knows/foaf:knows/foaf:name ?name .
}

이는 다음 SPARQL 질의와 같습니다.

SELECT ?x ?name {
    ?x  foaf:mbox <mailto:alice@example> .
    ?x  foaf:knows [ foaf:knows [ foaf:name ?name ]]. 
}

또는 명시적 변수를 사용하면 다음과 같습니다.

SELECT ?x ?name {
    ?x  foaf:mbox <mailto:alice@example> .
    ?x  foaf:knows ?a1 .
    ?a1 foaf:knows ?a2 .
    ?a2 foaf:name ?name .
}

중복 필터링: Alice가 아는 사람이 Alice 자신을 알고 있을 수도 있으므로, 위 예제에는 Alice 자신이 포함될 수 있습니다. 이는 다음으로 피할 수 있습니다.

{ ?x foaf:mbox <mailto:alice@example> .
  ?x foaf:knows/foaf:knows ?y .
  FILTER ( ?x != ?y )
  ?y foaf:name ?name 
}

역방향 속성 경로: 다음 두 질의는 같습니다. 두 번째는 속성 방향을 반대로 하여 주어와 객체의 역할을 바꾼 것뿐입니다.

{ ?x foaf:mbox <mailto:alice@example> }
{ <mailto:alice@example> ^foaf:mbox ?x }

역방향 경로 시퀀스: ?x가 아는 어떤 사람을 아는 모든 사람 찾기.

{
  ?x foaf:knows/^foaf:knows ?y .  
  FILTER(?x != ?y)
}

이는 다음과 동등합니다(?gen1은 시스템이 생성한 변수입니다).

{
  ?x foaf:knows ?gen1 .
  ?y foaf:knows ?gen1 .  
  FILTER(?x != ?y)
}

임의 길이 일치: foaf:knows를 통해 Alice에서 도달할 수 있는 모든 사람의 이름 찾기.

{
  ?x foaf:mbox <mailto:alice@example> .
  ?x foaf:knows+/foaf:name ?name .
}

임의 길이 경로의 대안:

{ ?ancestor (ex:motherOf|ex:fatherOf)+ <#me> }

임의 길이 경로 일치: 일부 형태의 제한된 추론도 가능합니다. 예를 들어 RDFS의 경우, 리소스의 모든 타입과 상위 타입은 다음과 같습니다.

{ <http://example/thing> rdf:type/rdfs:subClassOf* ?type }

모든 리소스와 그 모든 추론된 타입:

{ ?x rdf:type/rdfs:subClassOf* ?type }

하위 속성:

{ ?x ?p ?v . ?p rdfs:subPropertyOf* :property }

부정된 속성 경로: rdf:type으로 연결되지 않은 노드 찾기(어느 방향이든):

{ ?x !(rdf:type|^rdf:type) ?y }

RDF 컬렉션의 요소:

{ :list rdf:rest*/rdf:first ?element }

참고: 이 경로 표현식은 결과의 순서를 보장하지 않습니다.

9.3 속성 경로와 동등한 패턴

SPARQL 속성 경로는 RDF 트리플을 이름 있는 간선을 가진 방향성 있고, 순환 가능성이 있는 그래프로 취급합니다. 속성 경로 표현식의 평가는 중복으로 이어질 수 있습니다. 동등한 패턴에서 도입된 변수는 결과의 일부가 아니며 다른 곳에서 이미 사용되지 않기 때문입니다. 이들은 결과를 질의에서 주어진 변수만으로 암시적으로 투영함으로써 숨겨집니다.

예를 들어 다음 데이터에서:

PREFIX :       <http://example/>

:order  :item :z1 .
:order  :item :z2 .

:z1 :name "Small" .
:z1 :price 5 .

:z2 :name "Large" .
:z2 :price 5 .

질의:

PREFIX :   <http://example/>
SELECT * 
{  ?s :item/:price ?x . }

결과:

s x
<http://example/order> 5
<http://example/order> 5

반면 중간 변수(?_a)를 포함하도록 질의를 풀어 쓰면, 결과의 어떤 행도 중복되지 않습니다.

PREFIX :   <http://example/>
SELECT * 
{  ?s :item ?_a .
   ?_a :price ?x .
}

결과:

s _a x
<http://example/order> <http://example/z1> 5
<http://example/order> <http://example/z2> 5

그래프 패턴과의 동등성은 질의가 집계 연산도 포함하는 경우 특히 중요합니다. 주문의 총 비용은 다음으로 찾을 수 있습니다.

PREFIX :   <http://example/>
SELECT (sum(?x) AS ?total) { 
    :order :item/:price ?x
}
total
10

9.4 임의 길이 경로 일치

임의 길이의 속성 경로를 통한 주어와 객체 사이의 연결성은 "zero or more" 속성 경로 연산자 *와 "one or more" 속성 경로 연산자 +를 사용하여 찾을 수 있습니다. 또한 "zero or one" 연결성 속성 경로 연산자 ?도 있습니다.

이들 각 연산자는 연산자가 제한하는 횟수만큼 경로 단계를 사용하여 주어와 객체 사이의 연결을 찾기 위해 속성 경로 표현식을 사용합니다.

예를 들어 리소스의 가능한 모든 타입을, 리소스의 상위 타입을 포함하여 찾는 것은 다음으로 달성할 수 있습니다.

PREFIX  rdfs:   <http://www.w3.org/2000/01/rdf-schema#> . 
PREFIX  rdf:    <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT ?x ?type
{ 
    ?x rdf:type/rdfs:subClassOf* ?type
}

마찬가지로, foaf:knows 관계를 통해 :x가 연결되는 모든 사람을 찾는 것은 다음과 같습니다.

PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX :     <http://example/>
SELECT ?person
{ 
    :x foaf:knows+ ?person
}

이러한 연결성 일치는 중복을 도입하지 않습니다(연결이 이루어질 수 있는 방식의 수를 포함하지 않습니다). 반복된 경로 자체가 그렇지 않으면 중복을 초래할 수 있더라도 마찬가지입니다.

일치되는 그래프에는 순환이 포함될 수 있습니다. 연결성 일치는 순환을 일치시켜도 정의되지 않거나 무한한 결과로 이어지지 않도록 정의됩니다.

10. 할당

표현식의 값은 새 변수를 표현식의 값에 바인딩하여 해 매핑에 추가할 수 있으며, 이 값은 RDF 용어입니다. 그런 다음 변수는 질의에서 사용할 수 있고, 결과로도 반환될 수 있습니다.

이를 가능하게 하는 구문 형식은 세 가지입니다. BIND 키워드, SELECT 절의 표현식GROUP BY 절의 표현식입니다. 할당 형식은 (expression AS ?var)입니다.

표현식의 평가에서 오류가 발생하면, 해당 해에서 변수는 바인딩되지 않은 상태로 남지만 질의 평가는 계속됩니다.

인라인 데이터의 경우 VALUES를 사용하여 데이터를 질의에 직접 포함할 수도 있습니다.

10.1 BIND: 변수에 할당

BIND 형식은 기본 그래프 패턴 또는 속성 경로 표현식에서 값을 변수에 할당할 수 있게 합니다. BIND를 사용하면 앞선 기본 그래프 패턴이 종료됩니다. BIND 절이 도입하는 변수는 BIND에서 사용되는 지점까지 그룹 그래프 패턴 안에서 사용된 적이 없어야 합니다.

예제:

데이터:

PREFIX dc:   <http://purl.org/dc/elements/1.1/>
PREFIX :     <http://example.org/book/>
PREFIX ns:   <http://example.org/ns#>

:book1  dc:title     "SPARQL Tutorial" .
:book1  ns:price     42 .
:book1  ns:discount  0.2 .

:book2  dc:title     "The Semantic Web" .
:book2  ns:price     23 .
:book2  ns:discount  0.25 .

질의:

PREFIX  dc:  <http://purl.org/dc/elements/1.1/>
PREFIX  ns:  <http://example.org/ns#>

SELECT  ?title ?price
{   
    ?x ns:price ?p .
    ?x ns:discount ?discount
    BIND (?p*(1-?discount) AS ?price)
    FILTER(?price < 20)
    ?x dc:title ?title . 
}

동등한 질의(BIND는 기본 그래프 패턴을 종료하며, FILTER는 전체 그룹 그래프 패턴에 적용됩니다):

PREFIX  dc:  <http://purl.org/dc/elements/1.1/>
PREFIX  ns:  <http://example.org/ns#>

SELECT  ?title ?price
{  { ?x ns:price ?p .
     ?x ns:discount ?discount
     BIND (?p*(1-?discount) AS ?price)
    }
    {?x dc:title ?title . }
    FILTER(?price < 20)
}

결과:

title price
 "The Semantic Web" 17.25

10.2 VALUES: 인라인 데이터 제공

데이터는 그래프 패턴 안에 직접 작성하거나 VALUES를 사용하여 질의에 추가할 수 있습니다. VALUES해 시퀀스로서 인라인 데이터를 제공하며, 이는 조인 연산을 통해 질의 평가 결과와 결합됩니다. 이는 애플리케이션이 질의 결과에 대한 특정 요구사항을 제공하는 데 사용할 수 있으며, SERVICE 키워드를 통해 연합 질의를 제공하는 SPARQL 질의 엔진 구현이 원격 질의 서비스에 더 제약된 질의를 보내는 데도 사용할 수 있습니다.

10.2.1 VALUES 구문

VALUES는 데이터 블록에서 여러 변수를 지정할 수 있게 합니다. 하나의 변수와 몇몇 값만 지정하는 일반적인 경우를 위한 특별한 구문이 있습니다.

다음 예제에는 ?x?y 두 변수의 표가 있습니다. 두 번째 행에는 ?y에 대한 값이 없습니다.

VALUES (?x ?y) {
    (:uri1 1)
    (:uri2 UNDEF)
}

선택적으로, 하나의 변수와 몇몇 값이 있는 경우:

VALUES ?z { "abc" "def" }

이는 일반 형식을 사용하는 것과 같습니다.

VALUES (?z) { ("abc") ("def") }

동일한 변수는 VALUES 절의 변수 목록 안에서 여러 번 언급될 수 없다는 점에 유의하십시오.

10.2.2 VALUES 예제

VALUES 데이터 블록은 질의 패턴 안이나 하위 질의를 포함하는 SELECT 질의의 끝에 나타날 수 있습니다.

데이터:

PREFIX dc:   <http://purl.org/dc/elements/1.1/>
PREFIX :     <http://example.org/book/>
PREFIX ns:   <http://example.org/ns#>

:book1  dc:title  "SPARQL Tutorial" .
:book1  ns:price  42 .
:book2  dc:title  "The Semantic Web" .
:book2  ns:price  23 .

질의:

PREFIX dc:   <http://purl.org/dc/elements/1.1/> 
PREFIX :     <http://example.org/book/> 
PREFIX ns:   <http://example.org/ns#> 

SELECT ?book ?title ?price
{
    VALUES ?book { :book1 :book3 }
    ?book dc:title ?title ;
          ns:price ?price .
}

결과:

book title price
<http://example.org/book/book1> "SPARQL Tutorial" 42

VALUES 절의 특정 해에서 변수에 값이 없는 경우, RDF 용어 대신 UNDEF 키워드가 사용됩니다.

PREFIX dc:   <http://purl.org/dc/elements/1.1/> 
PREFIX :     <http://example.org/book/> 
PREFIX ns:   <http://example.org/ns#> 

SELECT ?book ?title ?price
{
    ?book dc:title ?title ;
          ns:price ?price .
    VALUES (?book ?title) {
        (UNDEF "SPARQL Tutorial")
        (:book2 UNDEF)
    }
}
book title price
<http://example.org/book/book1> "SPARQL Tutorial" 42
<http://example.org/book/book2> "The Semantic Web" 23

이 예제에서 VALUESSELECT 질의의 결과에 대해 실행되도록 지정될 수도 있었습니다.

PREFIX dc:   <http://purl.org/dc/elements/1.1/> 
PREFIX :     <http://example.org/book/> 
PREFIX ns:   <http://example.org/ns#> 

SELECT ?book ?title ?price {
    ?book dc:title ?title ;
          ns:price ?price .
}
VALUES (?book ?title) {
    (UNDEF "SPARQL Tutorial")
    (:book2 UNDEF)
}

이는 다른 질의이지만, 예제 상황에서는 같은 결과를 가집니다.

11. 집계

집계는 해의 그룹에 대해 표현식을 적용합니다. 기본적으로 해 집합은 모든 해를 포함하는 하나의 그룹으로 구성됩니다.

그룹화는 GROUP BY 구문을 사용하여 지정할 수 있습니다.

SPARQL 버전 1.1에서 정의된 집계는 COUNT, SUM, MIN, MAX, AVG, GROUP_CONCATSAMPLE입니다.

집계는 질의자가 단일 해가 아니라 해의 그룹에 대해 계산된 결과를 보고자 할 때 사용됩니다. 예를 들어 특정 변수가 취하는 각 값을 개별적으로 보는 것이 아니라 그 최대값을 보는 경우입니다.

11.1 집계 예제

데이터:

PREFIX : <http://books.example/>

:org1 :affiliates :auth1, :auth2 .
:auth1 :writesBook :book1, :book2 .
:book1 :price 9 .
:book2 :price 5 .
:auth2 :writesBook :book3 .
:book3 :price 7 .
:org2 :affiliates :auth3 .
:auth3 :writesBook :book4 .
:book4 :price 7 .

질의:

PREFIX : <http://books.example/>
SELECT (SUM(?lprice) AS ?totalPrice)
WHERE {
    ?org :affiliates ?auth .
    ?auth :writesBook ?book .
    ?book :price ?lprice .
}
GROUP BY ?org
HAVING (SUM(?lprice) > 10)

결과:

totalPrice
21

이 예제는 집계의 두 가지 기능을 보여 줍니다. GROUP BY는 하나 이상의 표현식(이 경우 ?org)에 따라 질의 해를 그룹화하며, HAVINGFILTER 표현식과 유사하지만 개별 해가 아니라 그룹에 대해 작동합니다.

이 예제는 GROUP BY 표현식에 따라 해를 그룹화하여 만들어집니다 (즉, ?org가 특정 값을 갖는 모든 해는 같은 그룹 안에 나타남). 그리고 해당 그룹에 대해 집합 함수 SUM을 평가합니다. 그런 다음 그룹은 HAVING 표현식으로 필터링되며, 이는 SUM(?lprice)가 10보다 크지 않은 모든 그룹을 제거합니다.

집계 질의와 하위 질의에서, 질의 패턴에 나타나지만 GROUP BY 절에는 없는 변수는 집계된 경우에만 투영하거나 select 표현식에서 사용할 수 있습니다. SAMPLE 집계는 이 목적에 사용할 수 있습니다. 자세한 내용은 투영 제한 절을 참조하십시오.

함수의 경우와 마찬가지로, 집계 표현식은 질의나 하위 질의에서 투영되기 위해 별칭을 가져야 한다는 점에 유의해야 합니다 (다시 말해 BIND 절과 비슷하게 AS 키워드를 사용합니다). 위 예제에서는 변수 ?totalPrice를 사용하여 이를 수행합니다. 집계가 다른 집계 투영이나 WHERE 절에서 이미 사용된 이름을 가진 변수로 투영되는 것은 오류입니다.

11.2 GROUP BY

해에 대한 집계 값을 계산하려면, 먼저 해를 하나 이상의 그룹으로 나누고 각 그룹에 대해 집계 값을 계산합니다.

SELECT, HAVING 또는 ORDER BY의 질의 수준에서 집계가 사용되지만 GROUP BY 항이 사용되지 않으면, 이는 모든 해가 속하는 하나의 암시적 그룹으로 간주됩니다.

GROUP BY 절 안에서는 GROUP BY (?x + ?y AS ?z)와 같이 바인딩 키워드 AS를 사용할 수 있습니다. 이는 { ... BIND (?x + ?y AS ?z) } GROUP BY ?z와 동등합니다.

예를 들어 해 시퀀스 S, ( {?x→2, ?y→3}, {?x→2, ?y→5}, {?x→6, ?y→7} )가 주어졌을 때, 해를 ?x 값에 따라 그룹화하고 각 그룹에 대해 ?y 값의 평균을 계산하고자 할 수 있습니다.

이는 다음과 같이 작성할 수 있습니다.

SELECT (AVG(?y) AS ?avg)
WHERE {
    ?a :x ?x ;
    :y ?y .
}
GROUP BY ?x

11.3 HAVING

HAVINGFILTER가 그룹화되지 않은 해 집합에 대해 작동하는 것과 같은 방식으로, 그룹화된 해 집합에 대해 작동합니다.

HAVING 표현식은 다음 절에 설명된 것처럼 그룹화된 질의의 투영과 동일한 평가 규칙을 가집니다.

HAVING 사용 예는 아래에 제시되어 있습니다.

PREFIX : <http://data.example/>
SELECT (AVG(?size) AS ?asize)
WHERE {
    ?x :size ?size
}
GROUP BY ?x
HAVING(AVG(?size) > 10)

이는 주어별로 그룹화된 평균 크기를 반환하지만, 평균 크기가 10보다 큰 경우에만 반환합니다.

11.4 집계 투영 제한

그룹화를 사용하는 질의 수준(명시적인 GROUP BY 절의 사용 또는 투영, HAVING, ORDER BY 절에서 집계를 사용하는 경우)에서, 해당 질의 수준의 투영 또는 SELECT 표현식에 나타나는 변수의 모든 출현은 다음 조건 중 하나를 반드시 만족해야 합니다.

이러한 변수 출현이 이 조건 중 하나를 만족하지 않으면, 질의는 구문적으로 유효하지 않습니다.

예를 들어 다음 질의는 ?x가 GROUP BY 항으로 주어졌으므로 합법적입니다.

PREFIX : <http://example.com/data/#>
SELECT ?x (MIN(?y) * 2 AS ?min)
WHERE {
    ?x :p ?y .
    ?x :q ?z .
} GROUP BY ?x (STR(?z))

STR(?z)를 투영하는 것은 합법적이지 않다는 점에 유의하십시오. 이 표현식은 단순 변수도 아니고, 이름 있는 GROUP BY 표현식도 아니기 때문입니다. 그러나 GROUP BY ?x (STR(?z) AS ?strZ)를 사용하면 ?strZ를 투영할 수 있습니다.

위 조건을 만족하지 않는 변수를 사용하는 다른 표현식은 SAMPLE 집계를 사용하여 해당 그룹에서 투영할 수 있습니다.

11.5 집계 예제(오류 포함)

이 절은 집계를 사용하는 예제 질의를 보여 주며, 집계가 있는 경우 결과에서 오류가 어떻게 처리되는지를 보여 줍니다.

데이터:

PREFIX : <http://example.com/data/#>

:x :p 1, 2, 3, 4 .
:y :p 1, _:b2, 3, 4 .
:z :p 1.0, 2.0, 3.0, 4 .

질의:

PREFIX : <http://example.com/data/#>
SELECT ?g (AVG(?p) AS ?avg) ((MIN(?p) + MAX(?p)) / 2 AS ?c)
WHERE {
    ?g :p ?p .
}
GROUP BY ?g

결과:

g avg c
<http://example.com/data/#x> 2.5 2.5
<http://example.com/data/#y>
<http://example.com/data/#z> 2.5 2.5

:y 그룹의 바인딩은 결과에 포함되지 않는다는 점에 유의하십시오. Avg({1, _:b2, 3, 4})의 평가와 (_:b2 + 4) / 2가 오류이므로, 해에서 바인딩이 제거되기 때문입니다.

12. 하위 질의

하위 질의는 SPARQL 질의를 다른 질의 안에 포함하는 방법으로, 일반적으로 질의 안의 어떤 하위 표현식에서 결과 수를 제한하는 것처럼 다른 방식으로는 달성할 수 없는 결과를 얻기 위해 사용됩니다.

SPARQL 질의 평가의 상향식 특성 때문에, 하위 질의는 논리적으로 먼저 평가되고 결과가 외부 질의로 투영됩니다.

하위 질의에서 투영된 변수만 외부 질의에 보이거나 범위 안에 있다는 점에 유의하십시오.

12.1 예제

데이터:

PREFIX : <http://people.example/>

:alice :name "Alice", "Alice Foo", "A. Foo" .
:alice :knows :bob, :carol .
:bob :name "Bob", "Bob Bar", "B. Bar" .
:carol :name "Carol", "Carol Baz", "C. Baz" .

Alice를 알고 이름이 있는 모든 사람에 대해 이름 하나(정렬 순서가 가장 낮은 것)를 반환합니다.

질의:

PREFIX : <http://people.example/>
PREFIX : <http://people.example/>

SELECT ?y ?minName
WHERE {
    :alice :knows ?y .
    {
      SELECT ?y (MIN(?name) AS ?minName)
      WHERE {
          ?y :name ?name .
      } GROUP BY ?y
    }
}

결과:

y minName
:bob "B. Bar"
:carol "C. Baz"

이 결과는 먼저 내부 질의를 평가하여 얻어집니다.

SELECT ?y (MIN(?name) AS ?minName)
WHERE {
    ?y :name ?name .
} GROUP BY ?y

이는 다음 해 시퀀스를 생성합니다.

y minName
:alice "A. Foo"
:bob "B. Bar"
:carol "C. Baz"

이는 외부 질의의 결과와 조인됩니다.

y
:bob
:carol

13. RDF 데이터셋

RDF 데이터 모델은 주어, 술어 및 객체를 가진 트리플로 구성된 그래프로 정보를 표현합니다. 많은 RDF 데이터 저장소는 여러 RDF 그래프를 보관하고 각 그래프에 대한 정보를 기록하여, 애플리케이션이 둘 이상의 그래프에서 온 정보를 포함하는 질의를 만들 수 있게 합니다.

SPARQL 질의는 그래프의 컬렉션을 나타내는 RDF 데이터셋 [RDF12-CONCEPTS]에 대해 실행됩니다. RDF 데이터셋은 이름이 없는 기본 그래프 하나와, 각각 IRI 또는 빈 노드로 식별되는 0개 이상의 명명된 그래프로 구성됩니다. SPARQL 질의는 13.3 데이터셋 질의 절에 설명된 대로 질의 패턴의 서로 다른 부분을 서로 다른 그래프에 일치시킬 수 있습니다.

RDF 데이터셋은 명명된 그래프를 0개 포함할 수 있습니다. RDF 데이터셋은 항상 하나의 기본 그래프를 포함합니다. 질의는 기본 그래프와의 일치를 포함할 필요가 없습니다. 질의는 명명된 그래프와의 일치만 포함할 수도 있습니다.

기본 그래프 패턴을 일치시키는 데 사용되는 그래프는 활성 그래프입니다. 앞 절들에서는 모든 질의가 RDF 데이터셋의 기본 그래프인 단일 그래프를 활성 그래프로 하여 실행되는 것으로 표시되었습니다. GRAPH 키워드는 질의의 일부에서 활성 그래프를 데이터셋의 모든 명명된 그래프 중 하나로 만들기 위해 사용됩니다.

13.1 RDF 데이터셋의 예

RDF 데이터셋의 정의 [RDF12-CONCEPTS]는 명명된 그래프와 기본 그래프의 관계를 제한하지 않습니다. 정보는 서로 다른 그래프에서 반복될 수 있으며, 그래프 사이의 관계가 노출될 수 있습니다. 유용한 두 가지 배치는 다음과 같습니다.

예제 1:
PREFIX dc: <http://purl.org/dc/elements/1.1/>

<http://example.org/bob>    dc:publisher  "Bob" .
<http://example.org/alice>  dc:publisher  "Alice" .

GRAPH <http://example.org/bob> {
    _:a foaf:name "Bob" .
    _:a foaf:mbox <mailto:bob@oldcorp.example.org> .
}

GRAPH <http://example.org/alice> {
    _:a foaf:name "Alice" .
    _:a foaf:mbox <mailto:alice@work.example.org> .
}

이 예제에서 기본 그래프는 두 명명된 그래프의 게시자 이름을 포함합니다. 이 예제에서 명명된 그래프의 트리플은 기본 그래프에 보이지 않습니다.

예제 2:

RDF 데이터는 그래프의 RDF 병합 [RDF12-SEMANTICS]으로 결합할 수 있습니다. RDF 데이터셋 안에서 가능한 그래프 배치 중 하나는 기본 그래프를 명명된 그래프의 정보 일부 또는 전부에 대한 RDF 병합으로 두는 것입니다.

다음 예제에서 명명된 그래프는 이전과 같은 트리플을 포함합니다. RDF 데이터셋은 빈 노드를 구별해 유지하는 명명된 그래프의 RDF 병합을 기본 그래프에 포함합니다.

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

_:x foaf:name "Bob" .
_:x foaf:mbox <mailto:bob@oldcorp.example.org> .

_:y foaf:name "Alice" .
_:y foaf:mbox <mailto:alice@work.example.org> .

GRAPH <http://example.org/bob> {
    _:a foaf:name "Bob" .
    _:a foaf:mbox <mailto:bob@oldcorp.example.org> .
}

GRAPH <http://example.org/alice> {
    _:a foaf:name "Alice" .
    _:a foaf:mbox <mailto:alice@work.example> .
}

RDF 병합에서 병합된 그래프의 빈 노드는 병합되는 그래프의 빈 노드와 공유되지 않습니다.

13.2 RDF 데이터셋 지정

SPARQL 질의는 RDF 데이터셋을 설명하기 위해 FROM 절과 FROM NAMED 절을 사용하여 일치에 사용할 데이터셋을 지정할 수 있습니다. 질의가 이러한 데이터셋 설명을 제공하면, 질의에 데이터셋 설명이 제공되지 않았을 때 질의 서비스가 사용할 데이터셋 대신 사용됩니다. RDF 데이터셋은 SPARQL 프로토콜 요청에서 지정될 수도 있으며, 이 경우 프로토콜 설명은 질의 자체의 설명을 재정의합니다. 데이터셋 설명이 서비스에 허용되지 않는 경우 질의 서비스는 질의 요청을 거부할 수 있습니다.

FROMFROM NAMED 키워드는 질의가 참조로 RDF 데이터셋을 지정할 수 있게 합니다. 이들은 데이터셋이 주어진 IRI(즉, 주어진 IRI 참조의 절대 형식)로 식별되는 리소스의 표현에서 얻어진 그래프를 포함해야 함을 나타냅니다. 여러 FROMFROM NAMED 절에서 생기는 데이터셋은 다음과 같습니다.

FROM 절이 없지만 하나 이상의 FROM NAMED 절이 있는 경우, 데이터셋은 기본 그래프로 빈 그래프를 포함합니다.

13.2.1 기본 그래프 지정

FROM 절은 기본 그래프를 형성하는 데 사용할 그래프를 나타내는 IRI를 포함합니다. 이는 그 그래프를 명명된 그래프로 넣지 않습니다.

이 예제에서 RDF 데이터셋은 하나의 기본 그래프를 포함하며 명명된 그래프는 없습니다.

# Default graph (located at http://example.org/foaf/aliceFoaf)
PREFIX  foaf:  <http://xmlns.com/foaf/0.1/>

_:a  foaf:name     "Alice" .
_:a  foaf:mbox     <mailto:alice@work.example> .
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT  ?name
FROM    <http://example.org/foaf/aliceFoaf>
WHERE   { ?x foaf:name ?name }
name
"Alice"

질의가 기본 그래프를 나타내기 위해 둘 이상의 IRI를 제공하는 FROM 절을 둘 이상 제공하는 경우, 기본 그래프는 주어진 IRI로 식별되는 리소스의 표현에서 얻어진 그래프의 RDF 병합입니다.

13.2.2 명명된 그래프 지정

질의는 FROM NAMED 절을 사용하여 RDF 데이터셋의 명명된 그래프에 대한 IRI를 제공할 수 있습니다. 각 IRI는 RDF 데이터셋에 하나의 명명된 그래프를 제공하는 데 사용됩니다. 둘 이상의 FROM NAMED 절에서 같은 IRI를 사용하면, 데이터셋에 그 IRI를 가진 하나의 명명된 그래프가 나타납니다.

# Graph: http://example.org/bob
PREFIX foaf: <http://xmlns.com/foaf/0.1/>

_:a foaf:name "Bob" .
_:a foaf:mbox <mailto:bob@oldcorp.example.org> .
# Graph: http://example.org/alice
PREFIX foaf: <http://xmlns.com/foaf/0.1/>

_:a foaf:name "Alice" .
_:a foaf:mbox <mailto:alice@work.example> .
...
FROM NAMED <http://example.org/alice>
FROM NAMED <http://example.org/bob>
...

FROM NAMED 구문은 IRI가 대응하는 그래프를 식별한다는 것을 시사하지만, RDF 데이터셋에서 IRI와 그래프의 관계는 간접적입니다. IRI는 리소스를 식별하며, 리소스는 그래프로 표현됩니다(더 정확히는 그래프를 직렬화한 문서로 표현됨). 자세한 내용은 [WEBARCH]를 참조하십시오.

13.2.3 FROM과 FROM NAMED 결합

FROM 절과 FROM NAMED 절은 같은 질의에서 사용할 수 있습니다.

# Default graph (located at http://example.org/dft.ttl)
PREFIX dc: <http://purl.org/dc/elements/1.1/>

<http://example.org/bob>    dc:publisher  "Bob Hacker" .
<http://example.org/alice>  dc:publisher  "Alice Hacker" .
# Named graph: http://example.org/bob
PREFIX foaf: <http://xmlns.com/foaf/0.1/>

_:a foaf:name "Bob" .
_:a foaf:mbox <mailto:bob@oldcorp.example.org> .
# Named graph: http://example.org/alice
PREFIX foaf: <http://xmlns.com/foaf/0.1/>

_:a foaf:name "Alice" .
_:a foaf:mbox <mailto:alice@work.example.org> .
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX dc: <http://purl.org/dc/elements/1.1/>

SELECT ?who ?g ?mbox
FROM <http://example.org/dft.ttl>
FROM NAMED <http://example.org/alice>
FROM NAMED <http://example.org/bob>
WHERE
{
    ?g dc:publisher ?who .
    GRAPH ?g { ?x foaf:mbox ?mbox }
}

이 질의에 대한 RDF 데이터셋은 하나의 기본 그래프와 두 개의 명명된 그래프를 포함합니다. GRAPH 키워드는 아래에 설명됩니다.

데이터셋을 구성하는 데 필요한 동작은 데이터셋 설명만으로 결정되지 않습니다. 데이터셋 설명에서 IRI가 두 번 주어진 경우, 두 개의 FROM 절을 사용하거나 FROM 절과 FROM NAMED 절을 사용하더라도, 해당 IRI와 관련된 RDF 그래프를 얻기 위해 정확히 한 번 또는 정확히 두 번 시도한다고 가정하지 않습니다. 따라서 데이터셋 설명의 두 발생에서 얻은 트리플의 빈 노드 정체성에 대해 어떤 가정도 할 수 없습니다. 일반적으로 그래프의 동등성에 대해 어떤 가정도 할 수 없습니다.

13.3 데이터셋 질의

그래프 컬렉션을 질의할 때, GRAPH 키워드는 명명된 그래프에 대해 패턴을 일치시키는 데 사용됩니다. GRAPH는 하나의 그래프를 선택하기 위해 IRI를 제공할 수도 있고, 질의의 RDF 데이터셋에 있는 모든 명명된 그래프의 IRI를 범위로 하는 변수를 사용할 수도 있습니다.

GRAPH를 사용하면 질의의 해당 부분 안에서 그래프 패턴을 일치시키는 활성 그래프가 변경됩니다. GRAPH 사용 밖에서는 기본 그래프를 사용하여 일치가 수행됩니다.

다음 두 그래프는 예제에서 사용됩니다.

# Named graph: http://example.org/foaf/aliceFoaf
PREFIX  foaf:     <http://xmlns.com/foaf/0.1/>
PREFIX  rdf:      <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX  rdfs:     <http://www.w3.org/2000/01/rdf-schema#>

_:a  foaf:name     "Alice" .
_:a  foaf:mbox     <mailto:alice@work.example> .
_:a  foaf:knows    _:b .

_:b  foaf:name     "Bob" .
_:b  foaf:mbox     <mailto:bob@work.example> .
_:b  foaf:nick     "Bobby" .
_:b  rdfs:seeAlso  <http://example.org/foaf/bobFoaf> .

<http://example.org/foaf/bobFoaf>
rdf:type      foaf:PersonalProfileDocument .
# Named graph: http://example.org/foaf/bobFoaf
PREFIX  foaf:     <http://xmlns.com/foaf/0.1/>
PREFIX  rdf:      <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX  rdfs:     <http://www.w3.org/2000/01/rdf-schema#>

_:z  foaf:mbox     <mailto:bob@work.example> .
_:z  rdfs:seeAlso  <http://example.org/foaf/bobFoaf> .
_:z  foaf:nick     "Robert" .

<http://example.org/foaf/bobFoaf>
        rdf:type      foaf:PersonalProfileDocument .

13.3.1 그래프 이름 접근

아래 질의는 데이터셋의 각 명명된 그래프에 대해 그래프 패턴을 일치시키고, src 변수가 일치된 그래프의 IRI에 바인딩된 해를 형성합니다. 그래프 패턴은 활성 그래프가 데이터셋의 각 명명된 그래프인 상태로 일치됩니다.

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

SELECT ?src ?bobNick
FROM NAMED <http://example.org/foaf/aliceFoaf>
FROM NAMED <http://example.org/foaf/bobFoaf>
WHERE
{
    GRAPH ?src
    { ?x foaf:mbox <mailto:bob@work.example> .
      ?x foaf:nick ?bobNick
    }
}

질의 결과는 정보가 발견된 그래프의 이름과 Bob의 nick 값을 제공합니다.

src bobNick
<http://example.org/foaf/aliceFoaf> "Bobby"
<http://example.org/foaf/bobFoaf> "Robert"

13.3.2 그래프 IRI로 제한

질의는 그래프 IRI를 제공하여 특정 그래프에 적용되는 일치를 제한할 수 있습니다. 이는 활성 그래프를 해당 IRI가 이름 붙인 그래프로 설정합니다. 이 질의는 http://example.org/foaf/bobFoaf 그래프에 주어진 Bob의 nick을 찾습니다.

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

SELECT ?nick
FROM NAMED <http://example.org/foaf/aliceFoaf>
FROM NAMED <http://example.org/foaf/bobFoaf>
WHERE
{
    GRAPH data:bobFoaf {
        ?x foaf:mbox <mailto:bob@work.example> .
        ?x foaf:nick ?nick 
    }
}

이는 하나의 해를 산출합니다.

nick
"Robert"

13.3.3 가능한 그래프 IRI 제한

GRAPH 절에서 사용된 변수는 다른 GRAPH 절이나 데이터셋의 기본 그래프에 대해 일치되는 그래프 패턴에서도 사용할 수 있습니다.

아래 질의는 IRI http://example.org/foaf/aliceFoaf를 가진 그래프를 사용하여 Bob의 프로필 문서를 찾습니다. 그런 다음 해당 그래프에 대해 다른 패턴을 일치시킵니다. 두 번째 GRAPH 절의 패턴은 첫 번째 GRAPH 절(변수 whom)에서 찾은 것과 동일한 메일 박스(변수 mbox로 제공됨)를 가진 사람에 대한 빈 노드(변수 w)를 찾습니다. Alice의 FOAF 파일에서 변수 whom과 일치하는 데 사용된 빈 노드는 프로필 문서의 빈 노드와 같지 않기 때문입니다(서로 다른 그래프에 있음).

PREFIX  data:  <http://example.org/foaf/>
PREFIX  foaf:  <http://xmlns.com/foaf/0.1/>
PREFIX  rdfs:  <http://www.w3.org/2000/01/rdf-schema#>

SELECT ?mbox ?nick ?ppd
FROM NAMED <http://example.org/foaf/aliceFoaf>
FROM NAMED <http://example.org/foaf/bobFoaf>
WHERE {
    GRAPH data:aliceFoaf {
        ?alice foaf:mbox <mailto:alice@work.example> ;
               foaf:knows ?whom .
        ?whom  foaf:mbox ?mbox ;
               rdfs:seeAlso ?ppd .
        ?ppd  a foaf:PersonalProfileDocument .
    }
    GRAPH ?ppd {
        ?w foaf:mbox ?mbox ;
           foaf:nick ?nick
    }
}
mbox nick ppd
<mailto:bob@work.example> "Robert" <http://example.org/foaf/bobFoaf>

Alice의 FOAF 파일에서 Bob의 nick을 제공하는 어떤 트리플도 Bob의 nick을 제공하는 데 사용되지 않습니다. 변수 nick을 포함하는 패턴이 ppd에 의해 특정 개인 프로필 문서로 제한되기 때문입니다.

13.3.4 명명된 그래프와 기본 그래프

질의 패턴은 기본 그래프와 명명된 그래프를 모두 포함할 수 있습니다. 이 예제에서 집계자는 두 번의 서로 다른 시점에 웹 리소스를 읽어 들였습니다. 그래프가 집계자에 읽힐 때마다 로컬 시스템에 의해 IRI가 부여됩니다. 그래프들은 거의 같지만 "Bob"의 이메일 주소가 변경되었습니다.

이 예제에서 기본 그래프는 출처 정보를 기록하는 데 사용되며, 실제로 읽힌 RDF 데이터는 시스템에 의해 서로 다른 IRI가 부여된 두 개의 별도 그래프에 보관됩니다. RDF 데이터셋은 두 개의 명명된 그래프와 그에 대한 정보로 구성됩니다.

RDF 데이터셋:

# Default graph
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX g:  <tag:example.org,2005-06-06:>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>

g:graph1 dc:publisher "Bob" .
g:graph1 dc:date "2004-12-06"^^xsd:date .

g:graph2 dc:publisher "Bob" .
g:graph2 dc:date "2005-01-10"^^xsd:date .
# Graph: locally allocated IRI: tag:example.org,2005-06-06:graph1
PREFIX foaf: <http://xmlns.com/foaf/0.1/>

_:a foaf:name "Alice" .
_:a foaf:mbox <mailto:alice@work.example> .

_:b foaf:name "Bob" .
_:b foaf:mbox <mailto:bob@oldcorp.example.org> .
# Graph: locally allocated IRI: tag:example.org,2005-06-06:graph2
PREFIX foaf: <http://xmlns.com/foaf/0.1/>

_:a foaf:name "Alice" .
_:a foaf:mbox <mailto:alice@work.example> .

_:b foaf:name "Bob" .
_:b foaf:mbox <mailto:bob@newcorp.example.org> .

이 질의는 사람의 이름과 정보가 발견된 날짜를 상세히 제공하면서 이메일 주소를 찾습니다.

PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX dc:   <http://purl.org/dc/elements/1.1/>

SELECT ?name ?mbox ?date
WHERE {
   ?g dc:publisher ?name ;
      dc:date ?date .
   GRAPH ?g { 
       ?person foaf:name ?name ; foaf:mbox ?mbox
   }
}

결과는 "Bob"의 이메일 주소가 변경되었음을 보여 줍니다.

name mbox date
"Bob" <mailto:bob@oldcorp.example.org> "2004-12-06"^^xsd:date
"Bob" <mailto:bob@newcorp.example.org> "2005-01-10"^^xsd:date

14. 기본 연합 질의

이 문서는 SPARQL 연합 확장의 구문을 포함합니다.

이 기능은 문서 SPARQL 1.1 Federated Query에 정의되어 있습니다.

15. 해 시퀀스와 수정자

질의 패턴은 해의 순서 없는 컬렉션을 생성하며, 각 는 변수에서 RDF 용어로의 부분 함수입니다. 그런 다음 이러한 해는 처음에는 특정한 순서가 없는 시퀀스(해 시퀀스)로 취급됩니다. 이후 시퀀스 수정자가 적용되어 다른 시퀀스를 만듭니다. 마지막으로, 이 후자의 시퀀스는 SPARQL 질의 형식의 결과 중 하나를 생성하는 데 사용됩니다.

해 시퀀스 수정자는 다음 중 하나입니다.

수정자는 위 목록에 제시된 순서로 적용됩니다.

15.1 ORDER BY

ORDER BY 절은 해 시퀀스의 순서를 설정합니다.

ORDER BY 절 뒤에는 표현식과 선택적 정렬 수정자(ASC() 또는 DESC())로 구성된 정렬 비교자의 시퀀스가 옵니다. 각 정렬 비교자는 오름차순(ASC() 수정자로 표시되거나 수정자가 없음) 또는 내림차순(DESC() 수정자로 표시됨)입니다.

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

SELECT ?name
WHERE { ?x foaf:name ?name }
ORDER BY ?name
PREFIX     :    <http://example.org/ns#>
PREFIX foaf:    <http://xmlns.com/foaf/0.1/>

SELECT ?name
WHERE { ?x foaf:name ?name ; :empId ?emp }
ORDER BY DESC(?emp)
PREFIX     :    <http://example.org/ns#>
PREFIX foaf:    <http://xmlns.com/foaf/0.1/>

SELECT ?name
WHERE { ?x foaf:name ?name ; :empId ?emp }
ORDER BY ?name DESC(?emp)

"<" 연산자(연산자 매핑연산자 확장성 참조)는 numerics, xsd:strings, xsd:booleansxsd:dateTimes 쌍의 상대적 순서를 정의합니다. IRI 쌍은 데이터 타입이 xsd:string인 리터럴로 비교하여 정렬됩니다.

SPARQL은 그렇지 않으면 정렬되지 않을 일부 종류의 RDF 용어 사이의 순서도 고정합니다.

  1. (가장 낮음) 이 해에서 변수 또는 표현식에 할당된 값이 없음.
  2. 빈 노드
  3. IRI
  4. RDF 리터럴
  5. 트리플 용어

SPARQL은 가능한 모든 RDF 용어의 전체 순서를 정의하지 않습니다. 구현은 연산자 확장성을 통해 전체 순서를 정의할 수 있습니다. 다음은 상대적 순서가 정의되지 않은 용어 쌍의 몇 가지 예입니다.

이 변수 바인딩 목록은 오름차순입니다.

RDF 용어 이유
바인딩되지 않은 결과가 가장 먼저 정렬됩니다.
_:z 빈 노드는 바인딩되지 않은 값 뒤에 옵니다.
_:a 빈 노드의 상대적 순서는 없습니다.
<http://script.example/Latin> IRI는 빈 노드 뒤에 옵니다.
<http://script.example/Кириллица> 23번째 위치의 문자 "К"는 유니코드 코드 포인트 0x41A를 가지며, 이는 0x4C("L")보다 높습니다.
<http://script.example/漢字> 23번째 위치의 문자 "漢"은 유니코드 코드 포인트 0x6F22를 가지며, 이는 0x41A("К")보다 높습니다.
"http://script.example/Latin" xsd:strings는 IRI 뒤에 옵니다.

정렬 비교자에 대한 두 해의 오름차순은 해 바인딩을 표현식에 대입하고 "<" 연산자로 비교하여 설정됩니다. 내림차순은 오름차순의 반대입니다.

두 해의 상대적 순서는 시퀀스의 첫 번째 정렬 비교자에 대한 두 해의 상대적 순서입니다. 해 바인딩의 대입이 같은 RDF 용어를 생성하는 해의 경우, 순서는 다음 정렬 비교자에 대한 두 해의 상대적 순서입니다. 두 해에 대해 평가된 어떤 정렬 표현식도 서로 다른 RDF 용어를 생성하지 않으면 두 해의 상대적 순서는 정의되지 않습니다.

해 시퀀스를 정렬하면 항상 같은 수의 해를 포함하는 시퀀스가 됩니다.

CONSTRUCT 또는 DESCRIBE 질의에 대한 해 시퀀스에서 ORDER BY를 사용하는 것은 직접적인 효과가 없습니다. 오직 SELECT만 결과 시퀀스를 반환하기 때문입니다. LIMITOFFSET과 함께 사용하면, ORDER BY는 해 시퀀스의 다른 슬라이스에서 생성된 결과를 반환하는 데 사용할 수 있습니다. ASK 질의는 ORDER BY, LIMIT 또는 OFFSET을 포함하지 않습니다.

15.2 투영

해 시퀀스는 변수의 부분집합만 포함하는 시퀀스로 변환될 수 있습니다. 시퀀스의 각 해에 대해 SELECT 질의 형식을 사용하여 지정된 변수 선택으로 새 해가 형성됩니다.

다음 예제는 FOAF 속성을 사용하여 RDF 그래프에 설명된 사람들의 이름만 추출하는 질의를 보여 줍니다.

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

_:a  foaf:name       "Alice" .
_:a  foaf:mbox       <mailto:alice@work.example> .

_:b  foaf:name       "Bob" .
_:b  foaf:mbox       <mailto:bob@work.example> .
PREFIX foaf:       <http://xmlns.com/foaf/0.1/>
SELECT ?name
WHERE
{ ?x foaf:name ?name }
name
"Bob"
"Alice"

15.3 중복 해

DISTINCT 또는 REDUCED 질의 수정자가 없는 해 시퀀스는 중복 해를 보존합니다.

데이터:

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

_:x    foaf:name   "Alice" .
_:x    foaf:mbox   <mailto:alice@example.com> .

_:y    foaf:name   "Alice" .
_:y    foaf:mbox   <mailto:asmith@example.com> .

_:z    foaf:name   "Alice" .
_:z    foaf:mbox   <mailto:alice.smith@example.com> .

질의:

PREFIX foaf:    <http://xmlns.com/foaf/0.1/>
SELECT ?name WHERE { ?x foaf:name ?name }

결과:

name
"Alice"
"Alice"
"Alice"

DISTINCTREDUCED 수정자는 중복이 질의 결과에 포함되는지 여부에 영향을 줍니다.

DISTINCT

DISTINCT 해 수정자는 중복 해를 제거합니다. 같은 변수를 같은 RDF 용어에 바인딩하는 해는 질의에서 하나만 반환됩니다.

PREFIX foaf:    <http://xmlns.com/foaf/0.1/>
SELECT DISTINCT ?name WHERE { ?x foaf:name ?name }
name
"Alice"

해 시퀀스 수정자의 순서에 따라, 중복은 limit 또는 offset이 적용되기 전에 제거된다는 점에 유의하십시오.

REDUCED

DISTINCT 수정자가 중복 해가 해 집합에서 제거되도록 보장하는 반면, REDUCED는 단순히 중복 해가 제거될 수 있도록 허용합니다. REDUCED 해 집합에서 어떤 해의 다중도는 적어도 1이며, DISTINCT 또는 REDUCED 수정자가 없는 해 집합에서 그 해의 다중도보다 크지 않습니다. 예를 들어 위 데이터를 사용하면, 질의

PREFIX foaf:    <http://xmlns.com/foaf/0.1/>
SELECT REDUCED ?name WHERE { ?x foaf:name ?name }

는 하나, 둘(여기에 표시됨) 또는 세 개의 해를 가질 수 있습니다.

name
"Alice"
"Alice"

15.4 OFFSET

OFFSET은 생성된 해가 지정된 수의 해 이후부터 시작되게 합니다. OFFSET이 0이면 아무 효과가 없습니다.

LIMITOFFSET을 사용하여 질의 해의 서로 다른 부분집합을 선택하는 것은 ORDER BY를 사용하여 순서를 예측 가능하게 만들지 않는 한 유용하지 않습니다.

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

SELECT  ?name
WHERE   { ?x foaf:name ?name }
ORDER BY ?name
LIMIT   5
OFFSET  10

15.5 LIMIT

LIMIT 절은 반환되는 해의 수에 상한을 둡니다. OFFSET이 적용된 후 실제 해의 수가 limit보다 크면, 최대 limit 수만큼의 해만 반환됩니다.

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

SELECT ?name
WHERE { ?x foaf:name ?name }
LIMIT 20

LIMIT이 0이면 결과가 반환되지 않습니다. limit는 음수일 수 없습니다.

16. 질의 형식

SPARQL에는 네 가지 질의 형식이 있습니다. 이 질의 형식들은 패턴 일치에서 나온 해를 사용하여 결과 집합 또는 RDF 그래프를 형성합니다. 질의 형식은 다음과 같습니다.

SELECT
질의 패턴 일치에서 바인딩된 변수 전체 또는 부분집합을 반환합니다.
CONSTRUCT
트리플 템플릿 집합의 변수들을 대입하여 구성한 RDF 그래프를 반환합니다.
ASK
질의 패턴이 일치하는지 여부를 나타내는 불리언을 반환합니다.
DESCRIBE
찾은 리소스를 설명하는 RDF 그래프를 반환합니다.

SPARQL 1.1 Query Results JSON Format, SPARQL Query Results XML Format (Second Edition) 또는 SPARQL 1.1 Query Results CSV and TSV Formats와 같은 형식은 SELECT 질의의 결과 집합이나 ASK 질의의 불리언 결과를 직렬화하는 데 사용할 수 있습니다.

16.1 SELECT

SELECT 결과 형식은 변수와 그 바인딩을 직접 반환합니다. 이는 필요한 변수를 투영하는 작업과 새 변수 바인딩을 질의 해에 도입하는 작업을 결합합니다.

16.1.1 투영

SELECT 절에 변수 이름 목록이 주어지면 특정 변수와 그 바인딩이 반환됩니다. 구문 SELECT *는 질의의 해당 지점에서 범위 안에 있는 모든 변수를 선택하는 축약입니다. 이는 FILTER에서만 사용되는 변수, MINUS의 오른쪽에서 사용되는 변수를 제외하며, 하위 질의를 고려합니다.

SELECT *의 사용은 질의가 그룹화를 사용하지 않는 경우에만 허용됩니다 (GROUP BY 절의 사용을 통해서든, HAVING 또는 ORDER BY 절에 집계가 존재하기 때문이든).

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

_:a    foaf:name   "Alice" .
_:a    foaf:knows  _:b .
_:a    foaf:knows  _:c .

_:b    foaf:name   "Bob" .

_:c    foaf:name   "Clare" .
_:c    foaf:nick   "CT" .
PREFIX foaf:    <http://xmlns.com/foaf/0.1/>
SELECT ?nameX ?nameY ?nickY
WHERE
{ ?x foaf:knows ?y ;
  foaf:name ?nameX .
  ?y foaf:name ?nameY .
  OPTIONAL { ?y foaf:nick ?nickY }
}
nameX nameY nickY
"Alice" "Bob"
"Alice" "Clare" "CT"

결과 집합은 로컬 API로 접근할 수 있으며, JSON, XML, CSV 또는 TSV로 직렬화할 수도 있습니다.

SPARQL 1.1 Query Results JSON Format:

{
    "head": {
        "vars": [ "nameX" , "nameY" , "nickY" ]
    } ,
    "results": {
        "bindings": [
          {
            "nameX": { "type": "literal" , "value": "Alice" } ,
            "nameY": { "type": "literal" , "value": "Bob" }
          } ,
          {
            "nameX": { "type": "literal" , "value": "Alice" } ,
            "nameY": { "type": "literal" , "value": "Clare" } ,
            "nickY": { "type": "literal" , "value": "CT" }
          }
        ]
    }
}

SPARQL Query Results XML Format (Second Edition):

<?xml version="1.0"?>
<sparql xmlns="http://www.w3.org/2005/sparql-results#">
<head>
<variable name="nameX"/>
<variable name="nameY"/>
<variable name="nickY"/>
</head>
<results>
<result>
<binding name="nameX">
<literal>Alice</literal>
</binding>
<binding name="nameY">
<literal>Bob</literal>
</binding>
</result>
<result>
<binding name="nameX">
<literal>Alice</literal>
</binding>
<binding name="nameY">
<literal>Clare</literal>
</binding>
<binding name="nickY">
<literal>CT</literal>
</binding>
</result>
</results>
</sparql>

16.1.2 SELECT 표현식

패턴 일치에서 어떤 변수를 결과에 포함할지 선택하는 것 외에도, SELECT 절은 새 변수를 도입할 수 있습니다. SELECT 표현식에서의 할당 규칙은 BIND의 할당 규칙과 같습니다. 표현식은 질의 해에 이미 있는 변수 바인딩 또는 SELECT 절 앞부분에서 정의된 바인딩을 결합하여 질의 해 안의 바인딩을 생성합니다.

(expr AS v)의 범위 지정은 즉시 적용됩니다. SELECT 표현식에서, 변수는 같은 SELECT 절의 뒤쪽 표현식에서 사용할 수 있으며, 같은 SELECT 절에서 다시 할당될 수 없습니다.

예제:

데이터:

PREFIX dc:   <http://purl.org/dc/elements/1.1/>
PREFIX :     <http://example.org/book/>
PREFIX ns:   <http://example.org/ns#>

:book1  dc:title  "SPARQL Tutorial" .
:book1  ns:price  42 .
:book1  ns:discount 0.2 .

:book2  dc:title  "The Semantic Web" .
:book2  ns:price  23 .
:book2  ns:discount 0.25 .

질의:

PREFIX  dc:  <http://purl.org/dc/elements/1.1/>
PREFIX  ns:  <http://example.org/ns#>
SELECT  ?title (?p*(1-?discount) AS ?price)
{ ?x ns:price ?p .
  ?x dc:title ?title . 
  ?x ns:discount ?discount 
}

결과:

title price
"The Semantic Web" 17.25
"SPARQL Tutorial" 33.6

새 변수는 같은 SELECT 절에서 구문적으로 앞서 도입된 경우 표현식에서도 사용할 수 있습니다.

PREFIX  dc:  <http://purl.org/dc/elements/1.1/>
PREFIX  ns:  <http://example.org/ns#>
SELECT  ?title (?p AS ?fullPrice) (?fullPrice*(1-?discount) AS ?customerPrice)
{ ?x ns:price ?p .
  ?x dc:title ?title . 
  ?x ns:discount ?discount 
}

결과:

title fullPrice customerPrice
"The Semantic Web" 23 17.25
"SPARQL Tutorial" 42 33.6

16.2 CONSTRUCT

CONSTRUCT 질의 형식은 그래프 템플릿으로 지정된 단일 RDF 그래프를 반환합니다. 결과는 해 시퀀스의 각 질의 해를 가져와 그래프 템플릿의 변수에 대입하고, 트리플을 집합 합집합으로 결합하여 형성된 RDF 그래프입니다.

이러한 인스턴스화가 바인딩되지 않은 변수를 포함하는 트리플이나 주어 또는 술어 위치의 리터럴과 같은 잘못된 RDF 구성을 생성하면, 해당 트리플은 출력 RDF 그래프에 포함되지 않습니다. 그래프 템플릿은 변수가 없는 트리플(ground 또는 explicit 트리플로 알려짐)을 포함할 수 있으며, 이들도 CONSTRUCT 질의 형식이 반환하는 출력 RDF 그래프에 나타납니다.

참고

"집합 합집합"에 의한 결과 그래프의 구성은 중복된 트리플이 그래프 직렬화에 나타나는지 여부를 강제하지 않습니다. 구현은 중복 트리플을 생성하거나 이를 중복 제거할 수 있습니다.

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

_:a    foaf:name   "Alice" .
_:a    foaf:mbox   <mailto:alice@example.org> .
PREFIX foaf:    <http://xmlns.com/foaf/0.1/>
PREFIX vcard:   <http://www.w3.org/2001/vcard-rdf/3.0#>
CONSTRUCT   { <http://example.org/person#Alice> vcard:FN ?name }
WHERE       { ?x foaf:name ?name }

는 FOAF 정보에서 vcard 속성을 만듭니다.

PREFIX vcard: <http://www.w3.org/2001/vcard-rdf/3.0#>

<http://example.org/person#Alice> vcard:FN "Alice" .

16.2.1 빈 노드가 있는 템플릿

템플릿은 빈 노드를 포함하는 RDF 그래프를 만들 수 있습니다. 템플릿 안의 빈 노드 식별자는 각 해에 대해 템플릿을 범위로 하지만, 질의 해에서 온 빈 노드는 범위가 제한되지 않습니다. 같은 식별자가 템플릿에서 두 번 나타나면, 모든 출현은 각 질의 해에 대해 생성되는 동일한 빈 노드로 대체되며, 서로 다른 질의 해에서 생성된 트리플에는 서로 다른 빈 노드가 있게 됩니다.

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

_:a    foaf:givenname   "Alice" .
_:a    foaf:family_name "Hacker" .

_:b    foaf:firstname   "Bob" .
_:b    foaf:surname     "Hacker" .
PREFIX foaf:    <http://xmlns.com/foaf/0.1/>
PREFIX vcard:   <http://www.w3.org/2001/vcard-rdf/3.0#>

CONSTRUCT {
     ?x  vcard:N _:v .
    _:v vcard:givenName ?gname .
    _:v vcard:familyName ?fname
} WHERE {
    { ?x foaf:firstname ?gname } UNION  { ?x foaf:givenname   ?gname } .
    { ?x foaf:surname   ?fname } UNION  { ?x foaf:family_name ?fname } .
}

는 FOAF 정보에 대응하는 vcard 속성을 만듭니다.

PREFIX vcard: <http://www.w3.org/2001/vcard-rdf/3.0#>

_:a vcard:N         _:v1 .
_:v1 vcard:givenName  "Alice" .
_:v1 vcard:familyName "Hacker" .

_:b vcard:N         _:v2 .
_:v2 vcard:givenName  "Bob" .
_:v2 vcard:familyName "Hacker" .

템플릿의 식별자 _:v를 가진 빈 노드는 두 질의 해 각각에 템플릿이 적용될 때 서로 다른 빈 노드로 대체됩니다. 이 예제에서는 결과 그래프에서 식별자 _:v1_:v2를 가진 빈 노드를 템플릿이 생성하게 됩니다.

식별자 _:a_:b로 표시된 질의 해의 빈 노드는 기반 RDF 데이터셋에서 유래하며 변경되지 않습니다.

16.2.2 RDF 데이터셋의 그래프 접근

CONSTRUCT를 사용하면 대상 RDF 데이터셋에서 그래프의 일부 또는 전체를 추출할 수 있습니다. 이 첫 번째 예제는 IRI 레이블 http://example.org/aGraph를 가진 그래프가 데이터셋에 있으면 그 그래프를 반환하고, 그렇지 않으면 빈 그래프를 반환합니다.

CONSTRUCT { ?s ?p ?o } WHERE { GRAPH <http://example.org/aGraph> { ?s ?p ?o } . }

그래프에 대한 접근은 다른 정보에 따라 조건부가 될 수 있습니다. 예를 들어 기본 그래프가 데이터셋의 명명된 그래프에 대한 메타데이터를 포함한다면, 다음과 같은 질의는 명명된 그래프에 대한 정보를 기반으로 하나의 그래프를 추출할 수 있습니다.

PREFIX  dc: <http://purl.org/dc/elements/1.1/>
PREFIX app: <http://example.org/ns#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>

CONSTRUCT { ?s ?p ?o } WHERE
{
    GRAPH ?g { ?s ?p ?o } .
    ?g dc:publisher <http://www.w3.org/> .
    ?g dc:date ?date .
    FILTER ( app:customDate(?date) > "2005-02-28T00:00:00Z"^^xsd:dateTime ) .
}

여기서 app:customDate는 날짜 형식을 xsd:dateTime RDF 용어로 바꾸는 확장 함수를 식별합니다.

16.2.3 해 수정자와 CONSTRUCT

질의의 해 수정자는 CONSTRUCT 질의의 결과에 영향을 줍니다. 이 예제에서 CONSTRUCT 템플릿의 출력 그래프는 그래프 패턴 일치에서 나온 해 중 두 개만으로부터 파생됩니다. 질의는 hit 수로 평가한 상위 두 사이트를 가진 사람들의 이름이 있는 그래프를 출력합니다. RDF 그래프의 트리플은 정렬되지 않습니다.

PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX site: <http://example.org/stats#>

_:a foaf:name "Alice" .
_:a site:hits 2349 .

_:b foaf:name "Bob" .
_:b site:hits 105 .

_:c foaf:name "Eve" .
_:c site:hits 181 .
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX site: <http://example.org/stats#>

CONSTRUCT { [] foaf:name ?name }
WHERE
{ [] foaf:name ?name ;
  site:hits ?hits .
}
ORDER BY desc(?hits)
LIMIT 2
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
_:x foaf:name "Alice" .
_:y foaf:name "Eve" .

16.2.4 CONSTRUCT WHERE

템플릿과 패턴이 같고 패턴이 단지 기본 그래프 패턴인 경우를 위해 CONSTRUCT 질의 형식의 짧은 형식이 제공됩니다(짧은 형식에서는 FILTER와 복잡한 그래프 패턴이 허용되지 않습니다). 짧은 형식에는 WHERE 키워드가 필요합니다.

다음 두 질의는 같습니다. 첫 번째는 두 번째의 짧은 형식입니다.

PREFIX foaf: <http://xmlns.com/foaf/0.1/>
CONSTRUCT WHERE { ?x foaf:name ?name }
PREFIX foaf: <http://xmlns.com/foaf/0.1/>

CONSTRUCT { ?x foaf:name ?name } 
WHERE
{ ?x foaf:name ?name }

16.3 ASK

애플리케이션은 질의 패턴에 해가 있는지 여부를 테스트하기 위해 ASK 형식을 사용할 수 있습니다. 가능한 질의 해에 대한 정보는 반환되지 않고, 단지 해가 존재하는지 여부만 반환됩니다.

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

_:a  foaf:name       "Alice" .
_:a  foaf:homepage   <http://work.example.org/alice/> .

_:b  foaf:name       "Bob" .
_:b  foaf:mbox       <mailto:bob@work.example> .
PREFIX foaf:    <http://xmlns.com/foaf/0.1/>
ASK  { ?x foaf:name  "Alice" }
true

이 결과 집합의 SPARQL Query Results XML Format (Second Edition) 형식은 다음을 제공합니다.

<?xml version="1.0"?>
                <sparql xmlns="http://www.w3.org/2005/sparql-results#">
                <head></head>
                <boolean>true</boolean>
                </sparql>

같은 데이터에서 다음은 Alice의 mbox가 언급되지 않았기 때문에 일치하지 않음을 반환합니다.

PREFIX foaf:    <http://xmlns.com/foaf/0.1/>
ASK  {
   ?x foaf:name  "Alice" ;
      foaf:mbox  <mailto:alice@work.example>
}
false

16.4 DESCRIBE (정보 제공)

DESCRIBE 형식은 리소스에 대한 RDF 데이터를 포함하는 단일 결과 RDF 그래프를 반환합니다. 이 데이터는 SPARQL 질의가 규정하는 것이 아니며, 그런 경우 질의 클라이언트는 데이터 소스에 있는 RDF의 구조를 알아야 합니다. 대신 이는 SPARQL 질의 처리기에 의해 결정됩니다. 질의 패턴은 결과 집합을 만드는 데 사용됩니다. DESCRIBE 형식은 해에서 식별된 각 리소스와 IRI로 직접 이름 붙은 모든 리소스를 가져와, 대상 RDF 데이터셋을 포함해 이용 가능한 어떤 정보에서도 나올 수 있는 "설명"을 취함으로써 단일 RDF 그래프를 조립합니다. 설명은 질의 서비스에 의해 결정됩니다. 구문 DESCRIBE *는 질의의 모든 변수를 설명하는 축약입니다.

16.4.1 명시적 IRI

DESCRIBE 절 자체는 리소스를 식별하기 위해 IRI를 취할 수 있습니다. 가장 단순한 DESCRIBE 질의는 DESCRIBE 절의 IRI 하나뿐입니다.

DESCRIBE <http://example.org/>

16.4.2 리소스 식별

설명할 리소스는 결과 집합의 질의 변수에 대한 바인딩에서도 가져올 수 있습니다. 이는 데이터셋에서 IRI로 식별되든 빈 노드로 식별되든 리소스의 설명을 가능하게 합니다.

PREFIX foaf:   <http://xmlns.com/foaf/0.1/>
DESCRIBE ?x
WHERE    { ?x foaf:mbox <mailto:alice@org> }

속성 foaf:mbox는 FOAF 어휘에서 역함수 속성으로 정의되어 있습니다. 그렇게 취급하면, 이 질의는 최대 한 사람에 대한 정보를 반환합니다. 그러나 질의 패턴에 여러 해가 있으면, 각 해에 대한 RDF 데이터는 모든 RDF 그래프 설명의 합집합입니다.

PREFIX foaf:   <http://xmlns.com/foaf/0.1/>
DESCRIBE ?x
WHERE    { ?x foaf:name "Alice" }

둘 이상의 IRI 또는 변수를 제공할 수 있습니다.

PREFIX foaf:   <http://xmlns.com/foaf/0.1/>
DESCRIBE ?x ?y <http://example.org/>
WHERE    {?x foaf:knows ?y}

16.4.3 리소스 설명

반환되는 RDF는 정보 게시자가 결정합니다. 이는 서비스가 설명되는 리소스와 관련 있다고 판단하는 정보일 수 있습니다. 다른 리소스에 대한 정보를 포함할 수도 있습니다. 예를 들어 책에 대한 RDF 데이터는 저자에 대한 세부 정보도 포함할 수 있습니다.

다음과 같은 단순한 질의는

PREFIX ent:  <http://org.example.com/employees#>
DESCRIBE ?x WHERE { ?x ent:employeeId "1234" }

직원에 대한 설명과 잠재적으로 유용한 다른 세부 정보를 반환할 수 있습니다.

PREFIX foaf:   <http://xmlns.com/foaf/0.1/>
PREFIX vcard:  <http://www.w3.org/2001/vcard-rdf/3.0>
PREFIX exOrg:  <http://org.example.com/employees#>
PREFIX rdf:    <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX owl:    <http://www.w3.org/2002/07/owl#>

_:a     exOrg:employeeId    "1234" ;
        foaf:mbox_sha1sum   "bee135d3af1e418104bc42904596fe148e90f033" ;
        vcard:N
          [ vcard:Family       "Smith" ;
            vcard:Given        "John"  ] .
foaf:mbox_sha1sum  rdf:type  owl:InverseFunctionalProperty .

이는 vCard 어휘 vcard:N에 대한 빈 노드 폐쇄를 포함합니다. 어떤 정보를 반환할지 결정하는 다른 가능한 메커니즘에는 Concise Bounded Descriptions [CBD]가 포함됩니다.

리소스가 일반적으로 빈 노드인 FOAF와 같은 어휘의 경우, foaf:mbox_sha1sum 역함수 속성과 같이 노드를 식별하기에 충분한 정보와, 이름 및 기록된 기타 세부 정보와 같은 정보를 반환하는 것이 적절할 것입니다. 예제에서는 WHERE 절과의 일치가 반환되었지만, 이것이 필수는 아닙니다.

17. 표현식과 값 테스트

SPARQL FILTERs는 주어진 제약에 따라 그래프 패턴 일치의 해를 제한합니다. 구체적으로, FILTERs는 표현식에 대입했을 때 유효 불리언 값이 false가 되거나 오류를 생성하는 모든 해를 제거합니다. 유효 불리언 값은 유효 불리언 값 절에 정의되어 있고, 오류는 평가 오류에 정의되어 있습니다.

RDF 리터럴은 리터럴의 값을 결정하는 데이터 타입을 가집니다.

PREFIX a:          <http://www.w3.org/2000/10/annotation-ns#>
PREFIX dc:         <http://purl.org/dc/elements/1.1/>

_:a   a:annotates   <http://www.w3.org/TR/rdf-sparql-query/> .
_:a   dc:date       "2004-12-31T19:00:00-05:00" .

_:b   a:annotates   <http://www.w3.org/TR/rdf-sparql-query/> .
_:b   dc:date       "2004-12-31T19:01:00-05:00"^^<http://www.w3.org/2001/XMLSchema#dateTime> .

첫 번째 dc:date 트리플의 객체는 데이터 타입이 xsd:string인 리터럴입니다. 두 번째는 데이터 타입이 xsd:dateTime입니다. 이들은 서로 다른 값을 가진 서로 다른 RDF 용어입니다.

SPARQL 표현식은 문법에 따라 구성되며, 함수(IRI로 명명됨)와 연산자 함수(SPARQL 문법의 키워드와 기호로 호출됨)에 접근할 수 있게 합니다. SPARQL 연산자는 리터럴의 값을 비교하는 데 사용할 수 있습니다.

PREFIX a:      <http://www.w3.org/2000/10/annotation-ns#>
PREFIX dc:     <http://purl.org/dc/elements/1.1/>
PREFIX xsd:    <http://www.w3.org/2001/XMLSchema#>

SELECT ?annot
WHERE { ?annot  a:annotates  <http://www.w3.org/TR/rdf-sparql-query/> .
        ?annot  dc:date      ?date .
        FILTER ( ?date > "2005-01-01T00:00:00Z"^^xsd:dateTime ) 
}

SPARQL 연산자는 17.3절에 나열되어 있으며 문법의 해당 생성식과 연결되어 있습니다.

또한 SPARQL은 17.5절에 나열된 XPath 캐스팅 함수의 부분집합을 포함하여 임의의 함수를 호출할 수 있는 기능을 제공합니다. 이러한 함수는 SPARQL 질의 안에서 이름(IRI)으로 호출됩니다. 예를 들면 다음과 같습니다.

... FILTER ( xsd:dateTime(?date) < xsd:dateTime("2005-01-01T00:00:00Z") ) ...

표기 규약: XPath 연산자는 접두사 op:로 표시됩니다. XPath 연산자는 네임스페이스가 없으며, op:는 표기상의 규약입니다.

SPARQL에서, XML 및 XML Schema에 의존하는 XPath and XQuery Functions and Operators 3.1 [XPATH-FUNCTIONS-31] 정의는 Extensible Markup Language (XML) 1.1 (Second Edition) [XML11] 및 W3C XML Schema Definition Language (XSD) 1.1 Part 2: Datatypes [XMLSCHEMA11-2]를 반드시 사용해야 합니다.

참고

XML 1.0 대 1.1 및 XML schema 1.0 대 1.1의 사용은 XPath and XQuery Functions and Operators 3.1에서 구현 정의입니다. 이는 특히 Extensible Markup Language (XML) 1.1 (Second Edition)에서 더 일반적인 Char의 정의에 영향을 줍니다.

17.1 피연산자 데이터 타입

SPARQL 함수와 연산자는 RDF 용어와 SPARQL 변수에 대해 작동합니다. 이러한 함수와 연산자의 일부는 XPath and XQuery Functions and Operators 3.1 [XPATH-FUNCTIONS-31]에서 가져온 것이며, XML Schema 타입이 지정된 값 인자와 반환 타입을 가집니다. 이러한 함수와 연산자에 인자로 전달된 RDF literalslexical form문자열 값데이터 타입 IRI에 대응하는 원자 데이터 타입을 가진 XML Schema 타입 값으로 매핑됩니다. 반환된 타입 값은 같은 방식으로 RDF literals로 다시 매핑됩니다.

SPARQL에는 RDF 용어의 특정 부분집합에 대해 작동하는 추가 연산자가 있습니다. 타입을 언급할 때, 다음 용어들은 대응하는 W3C XML Schema Definition Language (XSD) 1.1 Part 2: Datatypes [XMLSCHEMA11-2] 데이터 타입 IRI를 가진 literal을 나타냅니다.

다음 용어들은 SPARQL 값 테스트에서 사용되는 추가 타입을 식별합니다.

다음 타입들은 numeric 타입에서 파생되며, numeric 인자를 받는 함수와 연산자에 대한 유효한 인자입니다.

SPARQL 언어 확장은 XML schema 데이터 타입에서 파생된 것으로 취급되는 추가 타입을 다룰 수 있습니다.

17.2 표현식 평가

SPARQL 표현식은 해 매핑과 관련하여, 그리고 활성 그래프를 가진 RDF 데이터셋의 문맥에서 평가됩니다. 이러한 평가의 결과는 RDF 용어 또는 오류입니다.

SPARQL은 XPath and XQuery Functions and Operators가 정의한 함수와 연산자의 부분집합을 제공합니다. 다음 규칙은 XPath/XQuery와 SPARQL 사이의 데이터 및 실행 모델 차이를 수용합니다.

true(T), false (F) 및 오류(E)에 대한 logical-and와 logical-or 진리표는 다음과 같습니다.

A B A || B A && B
T T T T
T F T F
F T T F
F F F F
T E T E
E T T E
F E E F
E F E F
E E E E

17.2.1 호출

SPARQL은 인자 목록에 대해 함수를 호출하는 구문을 정의합니다. 달리 명시되지 않는 한, 이들은 다음과 같이 호출됩니다.

  • 인자 표현식이 평가되어 인자 값을 생성합니다. 인자 평가 순서는 정의되어 있지 않습니다.
  • 숫자 인자는 해당 함수 또는 연산자의 예상 타입에 맞도록 필요한 경우 승격됩니다.
  • 함수 또는 연산자가 인자 값에 대해 호출됩니다.

이 단계 중 하나라도 실패하면 호출은 오류를 생성합니다. 오류의 효과는 17.2 표현식 평가 절에 정의되어 있습니다.

각 형식에서 지정한 대로 함수와 다른 평가 규칙을 가진 "함수형 형식"도 있습니다.

17.2.2 평가 오류

표현식의 평가는 오류로 이어질 수 있습니다. 예를 들어 함수의 인자가 잘못된 데이터 타입의 리터럴이거나, 인자가 잘못된 종류의 RDF 용어인 경우입니다.

표현식의 평가가 오류를 발생시키면, 오류가 있는 표현식을 포함하는 모든 함수, 연산자 및 표현식의 평가도 오류를 발생시킵니다. 일부 함수형 형식은 해당 정의에 설명된 대로 오류를 처리합니다.

17.2.3 유효 불리언 값 (EBV)

유효 불리언 값logical-and, logical-or, 그리고 logical-not 논리 함수의 인자를 계산하고, FILTER 표현식의 결과를 평가하는 데 사용됩니다.

xsd:boolean  EBV (RDF term term)
  • 인자가 xsd:boolean데이터 타입 IRI를 가진 리터럴이고, 유효한 어휘 형식을 가진 경우, EBV 함수는 해당 인자를 반환합니다.
  • 인자가 numeric 타입에서 파생된 데이터 타입을 가진 리터럴이고, 인자가 유효한 어휘 형식을 가진 경우, 피연산자의 값이 NaN이거나 수치적으로 0과 같으면 EBV 함수는 리터럴 "false"^^xsd:boolean을 반환합니다. 그렇지 않으면 EBV 함수는 리터럴 "true"^^xsd:boolean을 반환합니다.
  • 인자가 xsd:string 데이터 타입 IRI를 가진 리터럴이고 값이 빈 문자열과 같으면, EBV 함수는 리터럴 "false"^^xsd:boolean을 반환합니다. 그렇지 않으면 EBV 함수는 리터럴 "true"^^xsd:boolean을 반환합니다.
  • 인자가 데이터 타입 IRI에 대해 유효하지 않은 어휘 형식을 가진 리터럴이면, 오류를 발생시킵니다.
  • 인자가 xsd:boolean, numeric 데이터 타입 또는 xsd:string이 아닌 데이터 타입 IRI를 가진 리터럴이면, 오류를 발생시킵니다.
  • 인자가 리터럴이 아니면, 오류를 발생시킵니다.
EBV 값
EBV("true"^^xsd:boolean) true
EBV("") false
EBV("1"^^xsd:boolean) true
EBV(-2e10) true
EBV(-0) false
EBV(<http://example/>) error
EBV("2025-08-18"^^xsd:date) error

true인 EBV는 xsd:boolean 데이터 타입 IRI와 "true" 어휘 값을 가진 리터럴로 표현됩니다. false인 EBV는 xsd:boolean 데이터 타입 IRI와 "false" 어휘 값을 가진 리터럴로 표현됩니다.

17.3 연산자 매핑

SPARQL 문법은 제약을 구성하는 데 사용되는 연산자 집합 (예: &&, *, isIRI)을 식별합니다. 다음 표는 이러한 각 문법 생성식을 적절한 피연산자 및 XPath and XQuery Functions and Operators 3.1 [XPATH-FUNCTIONS-31] 또는 17.4절에 지정된 SPARQL 연산자가 정의한 연산자 함수와 연결합니다. 주어진 매개변수 집합에 대한 연산자 정의를 선택할 때에는 가장 구체적인 매개변수를 가진 정의가 적용됩니다. 예를 들어 xsd:integer = xsd:signedInt를 평가할 때, 두 RDF 용어를 가진 정의가 아니라 두 numeric 매개변수를 가진 = 정의가 적용됩니다. 표는 가장 위쪽의 가능한 후보가 가장 구체적이도록 배치되어 있습니다. 적절한 피연산자 없이 호출된 연산자는 오류를 발생시킵니다.

SPARQL은 숫자 연산자에 대한 인자의 숫자 타입 승격 및 하위 타입 대체에 대해 XPath의 체계를 따릅니다. numeric 피연산자 (xsd:integer, xsd:decimal, xsd:float, xsd:double, 그리고 numeric 타입에서 파생된 타입)에 대한 XPath Operator Mapping 규칙은 SPARQL 연산자에도 적용됩니다(숫자 타입 승격하위 타입 대체의 정의는 XML Path Language (XPath) 3.1 [XPATH-31]를 참조하십시오). 일부 연산자는 중첩된 함수 표현식과 연결됩니다. 예: fn:not(op:numeric-equal(A, B)). XPath 정의에 따라, fn:notop:numeric-equal은 인자가 오류인 경우 오류를 생성한다는 점에 유의하십시오.

fn:compare에 대한 정렬은 XPath에서 정의되며 http://www.w3.org/2005/xpath-functions/collation/codepoint로 식별됩니다. 이 정렬은 코드 포인트 값에 기반한 문자열 비교를 허용합니다. 코드 포인트 문자열 동등성은 RDF 용어 동등성으로 테스트할 수 있습니다.

SPARQL 단항 연산자
연산자 Type(A) 함수 결과 타입
XQuery 단항 연산자
! A xsd:boolean (EBV) logical-not(A) xsd:boolean
+ A numeric op:numeric-unary-plus(A) numeric
- A numeric op:numeric-unary-minus(A) numeric
SPARQL 이항 연산자
연산자 Type(A) Type(B) 함수 결과 타입
논리 연결자
A || B xsd:boolean (EBV) xsd:boolean (EBV) logical-or(A, B) xsd:boolean
A && B xsd:boolean (EBV) xsd:boolean (EBV) logical-and(A, B) xsd:boolean
XPath 테스트
A = B numeric numeric op:numeric-equal(A, B) xsd:boolean
A = B xsd:string xsd:string op:numeric-equal(fn:compare(STR(A), STR(B)), 0) xsd:boolean
A = B xsd:boolean xsd:boolean op:boolean-equal(A, B) xsd:boolean
A = B xsd:dateTime xsd:dateTime op:dateTime-equal(A, B) xsd:boolean
A != B numeric numeric fn:not(op:numeric-equal(A, B)) xsd:boolean
A != B xsd:string xsd:string fn:not(op:numeric-equal(fn:compare(STR(A), STR(B)), 0)) xsd:boolean
A != B xsd:boolean xsd:boolean fn:not(op:boolean-equal(A, B)) xsd:boolean
A != B xsd:dateTime xsd:dateTime fn:not(op:dateTime-equal(A, B)) xsd:boolean
A < B numeric numeric op:numeric-less-than(A, B) xsd:boolean
A < B xsd:string xsd:string op:numeric-equal(fn:compare(STR(A), STR(B)), -1) xsd:boolean
A < B xsd:boolean xsd:boolean op:boolean-less-than(A, B) xsd:boolean
A < B xsd:dateTime xsd:dateTime op:dateTime-less-than(A, B) xsd:boolean
A > B numeric numeric op:numeric-greater-than(A, B) xsd:boolean
A > B xsd:string xsd:string op:numeric-equal(fn:compare(STR(A), STR(B)), 1) xsd:boolean
A > B xsd:boolean xsd:boolean op:boolean-greater-than(A, B) xsd:boolean
A > B xsd:dateTime xsd:dateTime op:dateTime-greater-than(A, B) xsd:boolean
A <= B numeric numeric logical-or(op:numeric-less-than(A, B), op:numeric-equal(A, B)) xsd:boolean
A <= B xsd:string xsd:string fn:not(op:numeric-equal(fn:compare(STR(A), STR(B)), 1)) xsd:boolean
A <= B xsd:boolean xsd:boolean fn:not(op:boolean-greater-than(A, B)) xsd:boolean
A <= B xsd:dateTime xsd:dateTime fn:not(op:dateTime-greater-than(A, B)) xsd:boolean
A >= B numeric numeric logical-or(op:numeric-greater-than(A, B), op:numeric-equal(A, B)) xsd:boolean
A >= B xsd:string xsd:string fn:not(op:numeric-equal(fn:compare(STR(A), STR(B)), -1)) xsd:boolean
A >= B xsd:boolean xsd:boolean fn:not(op:boolean-less-than(A, B)) xsd:boolean
A >= B xsd:dateTime xsd:dateTime fn:not(op:dateTime-less-than(A, B)) xsd:boolean
XPath 산술
A * B numeric numeric op:numeric-multiply(A, B) numeric
A / B numeric numeric op:numeric-divide(A, B) numeric; 단 두 피연산자가 모두 xsd:integer이면 xsd:decimal
A + B numeric numeric op:numeric-add(A, B) numeric
A - B numeric numeric op:numeric-subtract(A, B) numeric
SPARQL 테스트
A = B IRI IRI sameTerm(A, B) xsd:boolean
A = B 빈 노드 빈 노드 sameTerm(A, B) xsd:boolean
A = B 트리플 용어 트리플 용어 ( A.subject = B.subject ) &&
( A.predicate = B.predicate ) &&
( A.object = B.object )
xsd:boolean
A != B IRI IRI fn:not(sameTerm(A, B)) xsd:boolean
A != B 빈 노드 빈 노드 fn:not(sameTerm(A, B) xsd:boolean
A != B 트리플 용어 트리플 용어 ( A.subject != B.subject ) ||
( A.predicate != B.predicate ) ||
( A.object != B.object )
xsd:boolean
A = B RDF term RDF term sameValue(A, B) xsd:boolean
A != B RDF term RDF term fn:not(sameValue(A, B)) xsd:boolean

"(EBV)"로 표시된 xsd:boolean 함수 인자는 해당 인자의 유효 불리언 값을 평가하여 xsd:boolean으로 강제 변환됩니다.

트리플 용어에 적용된 연산자 =!=는 각 구성 요소에 연산자를 적용합니다.

17.3.1 연산자 확장성

SPARQL 언어 확장은 연산자와 연산자 함수 사이의 추가 연결을 제공할 수 있으며, 이는 위 표에 행을 추가하는 것과 같습니다. 추가 연산자는 오류 이외의 어떤 결과도 대체하는 결과를 산출할 수 없습니다. 이 규칙의 결과로, SPARQL FILTER는 확장되지 않은 구현과 비교하여 FILTER를 적용한 뒤 적어도 같은 중간 바인딩을 생성합니다.

'<' 연산자의 추가 매핑은 피연산자의 상대적 순서, 특히 ORDER BY 절에서 사용될 때의 상대적 순서를 제어할 것으로 예상됩니다.

17.4 函数定义

本节定义由 SPARQL 查询语言引入的运算符和函数。 示例展示这些运算符在由适当文法结构调用时的行为。

17.4.1 函数形式

17.4.1.1 BOUND
xsd:boolean  BOUND (variable var)

如果 var 被绑定到一个值,则返回 true。 否则返回 false。值为 NaN 或 INF 的变量被视为已绑定。

数据:

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

_:a  foaf:givenName  "Alice".

_:b  foaf:givenName  "Bob" .
_:b  dc:date         "2005-04-04T04:04:04Z"^^xsd:dateTime .
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX dc:   <http://purl.org/dc/elements/1.1/>
PREFIX xsd:   <http://www.w3.org/2001/XMLSchema#>
SELECT ?givenName
WHERE {
   ?x foaf:givenName  ?givenName .
   OPTIONAL { ?x dc:date ?date } .
   FILTER ( bound(?date) )
}

查询结果:

givenName
"Bob"

可以通过指定一个 OPTIONAL 图模式来测试某个图模式是否 被表达,该图模式引入一个变量,然后测试该变量是否未 绑定。 这在逻辑编程中称为失败即否定

此查询匹配具有 name没有表达 date 的人员:

PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX dc:   <http://purl.org/dc/elements/1.1/>
SELECT ?name
WHERE { 
    ?x foaf:givenName  ?name .
    OPTIONAL { ?x dc:date ?date } .
    FILTER (!bound(?date))
 }

查询结果:

name
"Alice"

由于 Bob 的 dc:date 是已知的,"Bob" 不是该查询的解。

17.4.1.2 IF
rdfTerm  IF (expression1, expression2, expression3)

IF 函数形式对第一个参数求值,将其解释为 有效布尔值,然后如果 EBV 为 true,则返回 expression2 的值;否则返回 expression3 的值。expression2expression3 中只有一个会被求值。如果对第一个参数求值引发错误, 则对 IF 表达式求值会引发一个错误

示例:假设在某个查询解中,?x 绑定到 2?z 绑定到 0, 并且 ?y 未绑定:

IF(?x = 2, "yes", "no") 返回 "yes"
IF(bound(?y), "yes", "no") 返回 "no"
IF(?x=2, "yes", 1/?z) 返回 "yes",表达式 1/?z 不会被求值
IF(?x=1, "yes", 1/?z) 引发错误
IF("2" > 1, "yes", "no") 引发错误
17.4.1.3 COALESCE
rdfTerm COALESCE(expression, ....)

COALESCE 函数形式返回第一个求值不产生错误的 表达式的 RDF 项值。 在 SPARQL 中,对未绑定变量求值会引发错误。

如果没有任何表达式求值时不产生错误,则引发错误。

如果表达式数量为零,则引发错误。

示例:假设在某个查询解中 ?x = 2 且 ?y 未绑定:

COALESCE(?x, 1/0) 返回 2,即 x 的值
COALESCE(1/0, ?x) 返回 2
COALESCE(5, ?x) 返回 5
COALESCE(?y, 3) 返回 3
COALESCE(?y) 引发错误,因为 y 未绑定。
COALESCE() 引发错误,因为参数数量为零。
17.4.1.4 NOT EXISTS 与 EXISTS

有一个过滤器运算符 EXISTS,它接受一个图模式。 EXISTS 返回 truefalse, 具体取决于该模式与解映射一起是否匹配数据集。 不会发生变量的额外绑定。NOT EXISTS 形式 会转换为 fn:not(EXISTS {...})

xsd:boolean  NOT EXISTS { pattern }

如果 pattern 匹配,则返回 false。 否则返回 true

NOT EXISTS { pattern } 等价于 fn:not(EXISTS { pattern })

xsd:boolean EXISTS { pattern }

如果 pattern 匹配,则返回 true。 否则返回 false

形式上,对于每个形式为 EXISTS { pattern }表达式 expr, 相对于解映射 μ、 在具有活动图 G数据集 D上下文中 求值 expr 的结果为:

  • 如果 eval(D(G), A, μ) 非空,则为 "true"^^xsd:boolean
  • 如果 eval(D(G), A, μ) 为空,则为 "false"^^xsd:boolean

其中 A 是按照18.3 到代数 语法的转换,通过转换 { pattern } 获得的 代数查询表达式

按照文法中的 ExistsFunc 产生式, { pattern } 匹配 GroupGraphPattern 产生式。 18.3 到代数语法的转换中涵盖任何 GroupGraphPattern 转换的具体小节 是18.3.2.6 转换图模式

17.4.1.5 logical-or
xsd:boolean logical-or (xsd:boolean left, xsd:boolean right)

此函数不能在表达式中直接使用。 此函数的目的是定义“||”运算符的语义。

该函数返回 leftright 的逻辑 OR。请注意,logical-or 作用于其每个参数的有效布尔值

注:关于 || 运算符如何处理错误,见 17.2 表达式求值一节。

17.4.1.6 logical-and
xsd:boolean logical-and (xsd:boolean left, xsd:boolean right)

此函数不能在表达式中直接使用。 此函数的目的是定义“&&” 运算符的语义。

该函数返回 leftright 的逻辑 AND。请注意,logical-and 作用于其每个参数的有效布尔值

注:关于 && 运算符如何处理错误,见 17.2 表达式求值一节。

17.4.1.7 logical-not
xsd:boolean logical-not (xsd:boolean arg)

此函数不能在表达式中直接使用。此函数的目的是 定义“!”运算符的语义。

该函数返回 arg 的逻辑 NOT。 请注意,logical-not 作用于其 参数的有效布尔值

17.4.1.8 IN
boolean  rdfTerm IN (expression, ...)

IN 运算符测试左侧的 RDF 项是否出现在 右侧表达式值的列表中。该测试使用 “=” 运算符完成, 后者按照运算符映射所确定的方式 测试是否为同一值。

右侧含有零个项的列表是合法的,并且求值为 false

比较中的错误会导致 IN 表达式 引发错误,前提是正在测试的 RDF 项未在该项列表的 其他位置找到。

如果 IN 与一个表达式一起用于产生 rdfTerm,则该表达式只会在求值 IN 表达式之前求值一次。

IN 运算符等价于以下 SPARQL 表达式:

(rdfTerm = value of expression1) || (rdfTerm = value of expression2) || ...

示例:

2 IN (1, 2, 3) true
2 IN () false
2 IN (<http://example/iri>, "str", 2.0) true
2 IN (1/0, 2) true
2 IN (2, 1/0) true
2 IN (3, 1/0) 引发错误
17.4.1.9 NOT IN
boolean  rdfTerm NOT IN (expression, ...)

NOT IN 运算符测试左侧的 RDF 项是否 未出现在右侧表达式列表的值中。该测试使用 “!=” 运算符完成,后者按照 运算符映射所确定的方式 测试两个值是否不是同一值。

右侧含有零个项的列表是合法的,并且求值为 true

如果 NOT IN 与一个表达式一起用于产生 rdfTerm,则该表达式只会在求值 NOT IN 表达式之前求值一次。

比较中的错误会导致 NOT IN 表达式引发错误,前提是 正在测试的 RDF 项未在该项列表的其他位置找到。

NOT IN 运算符等价于以下 SPARQL 表达式:

(rdfTerm != value of expression1) && (rdfTerm != value of expression2) && ...

NOT IN (...) 等价于 !(IN (...))

示例:

2 NOT IN (1, 2, 3) false
2 NOT IN () true
2 NOT IN (<http://example/iri>, "str", 2.0) false
2 NOT IN (1/0, 2) false
2 NOT IN (2, 1/0) false
2 NOT IN (3, 1/0) 引发错误

17.4.2 RDF 项上的函数

17.4.2.1 sameTerm
xsd:boolean  sameTerm (RDF term term1, RDF term term2)

如果 term1term2RDF 1.2 概念与抽象数据 模型 [RDF12-CONCEPTS] 中定义的同一 RDF 项,则返回 TRUE;否则返回 FALSE。

如果以下任一条件为 true,则 term1term2同一 RDF 项

sameTerm(<http://example/>, <http://example/>) true
sameTerm(<http://example/>, <https://example/>) false
sameTerm("abc", "abc") true
sameTerm("abc"@en, "abc") false
sameTerm("abc"@en, "abc"@EN) true
sameTerm("abc"@en--rtl, "abc"@en) false
sameTerm(2, 2.0) false
sameTerm(2, "2"^^xsd:integer) true
sameTerm(2, "02"^^xsd:integer) false
17.4.2.2 sameValue

此函数取代 SPARQL 1.1 中的 RDFterm-equal

xsd:boolean sameValue (RDF term term1, RDF term term2)

此函数不能在表达式中直接使用。此函数的目的是 在 “=” 运算符应用于两个 RDF 项,且它们不属于 17.3 运算符 映射一节中运算符映射表所涵盖的具体情形时, 定义该运算符的语义。

此函数的结果通过执行以下步骤确定。

  1. 如果 term1term2相等的 RDF 项, 则返回 TRUE。
  2. 如果 term1term2IRIblank node, 则返回 FALSE。
  3. 如果 term1term2 中恰好一个是 triple term, 则返回 FALSE。
  4. 如果 term1term2 都是 triple terms, 则将 sameValue 函数两两应用于每个组成部分。 如果每个组成部分对都返回 TRUE,则返回 TRUE; 如果任何组成部分对产生错误, 则产生一个错误; 否则返回 FALSE。
  5. 如果 term1term2 都是 literals, 且其中一个或两个字面量已知为 病态类型, 则产生一个错误
  6. "NaN"^^xsd:double"NaN"^^xsd:float 被视为 表示同一值。 如果 term1term2 对于 xsd:double 或 xsd:float 均为 "NaN",则返回 TRUE。
  7. 如果 term1term2 都是 literals, 且 SPARQL 处理器能够确定它们的值相等, 则返回 TRUE。
  8. 如果 term1term2 都是 literals, 且 SPARQL 处理器能够确定它们的值 不相等,则返回 FALSE。
  9. 否则,产生一个错误

如果两个参数都是字面量,则在 SPARQL 处理器能够确定 这些字面量的值相等或不相等的情况下,函数 sameValue 返回 truefalse。 如果 SPARQL 处理器无法确定,则返回 error

如果一个字面量的数据类型由 SPARQL 处理器处理,且其词汇形式不在该数据类型的 词汇空间 中,则该字面量为 病态类型

对于 xsd:double 和 xsd:float,+0-00 是同一 值。

=”的运算符映射 是函数 op:numeric-equal, 其定义是在比较涉及 NaN 的参数时返回 false。 然而,sameTerm("NaN"^^xsd:double, "NaN"^^xsd:double) 为 true。 函数 sameValuesameValue("NaN"^^xsd:double, "NaN"^^xsd:double) 定义为 true,因为这些参数是值空间中的同一元素。 类似地,函数 sameValuesameValue("NaN"^^xsd:float, "NaN"^^xsd:float) 定义为 true。

sameValue"NaN"^^xsd:double"NaN"^^xsd:float 的值视为同一值。 sameValue("NaN"^^xsd:double, "NaN"^^xsd:float)sameValue("NaN"^^xsd:float, "NaN"^^xsd:double) 都为 true

示例:

sameValue 结果
sameValue(1e10, "NaN"^^xsd:double) false
sameValue("NaN"^^xsd:double, "NaN"^^xsd:double) true
sameValue("NaN"^^xsd:double, "NaN"^^xsd:float) true
sameValue( <<(:s :p 123)>> , <<(:s :p 123.0)>> ) true

扩展实现可以支持字面量的附加数据类型。处理一个查询的实现, 在测试具有未识别数据类型(且词汇形式和 datatype IRI 不相同)的字面量是否等价时,会返回错误,表示它无法确定 被比较字面量的值是否等价。例如,未扩展的实现 在测试 "iiii"^^my:romanNumeral = "iv"^^my:romanNumeral 时会产生错误。

17.4.2.3 isIRI
xsd:boolean  isIRI (RDF term term)
xsd:boolean  isURI (RDF term term)

如果 term 是一个 IRI,则返回 true。 否则返回 falseisURIisIRI 运算符的另一种拼写。

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

_:a  foaf:name       "Alice".
_:a  foaf:mbox       <mailto:alice@work.example> .

_:b  foaf:name       "Bob" .
_:b  foaf:mbox       "bob@work.example" .

此查询匹配具有 namemboxmbox 是 IRI 的人员:

PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name ?mbox
WHERE {
    ?x foaf:name  ?name ;
       foaf:mbox  ?mbox .
    FILTER isIRI(?mbox) 
}

查询结果:

name mbox
"Alice" <mailto:alice@work.example>
17.4.2.4 isBLANK
xsd:boolean  isBLANK (RDF term term)

如果 term 是一个 blank node,则返回 true。否则返回 false

PREFIX a:          <http://www.w3.org/2000/10/annotation-ns#>
PREFIX dc:         <http://purl.org/dc/elements/1.1/>
PREFIX foaf:       <http://xmlns.com/foaf/0.1/>

_:a   a:annotates   <http://www.w3.org/TR/rdf-sparql-query/> .
_:a   dc:creator    "Alice B. Toeclips" .

_:b   a:annotates   <http://www.w3.org/TR/rdf-sparql-query/> .
_:b   dc:creator    _:c .
_:c   foaf:given    "Bob".
_:c   foaf:family   "Smith".

此查询匹配其 dc:creator 使用来自 FOAF 词汇表的谓词来表达 姓名的人员。

PREFIX a:      <http://www.w3.org/2000/10/annotation-ns#>
PREFIX dc:     <http://purl.org/dc/elements/1.1/>
PREFIX foaf:   <http://xmlns.com/foaf/0.1/>

SELECT ?given ?family
WHERE { 
    ?annot  a:annotates  <http://www.w3.org/TR/rdf-sparql-query/> .
    ?annot  dc:creator   ?c .
    OPTIONAL { ?c  foaf:given   ?given ; foaf:family  ?family } .
    FILTER isBLANK(?c)
}

查询结果:

given family
"Bob" "Smith"

在此示例中,dc:creator 谓词有两个宾语,但 只有一个(_:c)是空白节点。

17.4.2.5 isLITERAL
xsd:boolean  isLITERAL (RDF term term)

如果 term 是一个 literal,则返回 true。否则返回 false

PREFIX foaf:       <http://xmlns.com/foaf/0.1/>
                
_:a  foaf:name       "Alice".
_:a  foaf:mbox       <mailto:alice@work.example> .

_:b  foaf:name       "Bob" .
_:b  foaf:mbox       "bob@work.example" .

此查询类似于 17.4.2.1 中的查询, 但它匹配具有 namemboxmbox 是字面量的人员。这可用于查找错误数据 (foaf:mbox 应该只把 IRI 作为其宾语)。

PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name ?mbox
WHERE {
    ?x foaf:name  ?name ;
       foaf:mbox  ?mbox .
    FILTER isLiteral(?mbox)
}

查询结果:

name mbox
"Bob" "bob@work.example"
17.4.2.6 isNUMERIC
xsd:boolean  isNUMERIC (RDF term term)

如果 term 是数值,则返回 true。 否则返回 false。如果 term 具有适当的数据类型 (见操作数数据类型一节)并且具有 有效词汇形式,使其成为接受数值参数的函数和运算符的有效参数, 则 term 是数值。

示例:

isNUMERIC(12) true
isNUMERIC("12") false
isNUMERIC("12"^^xsd:nonNegativeInteger) true
isNUMERIC("1200"^^xsd:byte) false
isNUMERIC(<http://example/>) false
17.4.2.7 STR
xsd:string  STR (literal literal)
xsd:string  STR (IRI rsrc)

返回 literal(一个 literal)的 词汇形式;返回 rsrc(一个 IRI)的码位表示。这有助于检查 IRI 的各个部分,例如主机名。

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

_:a  foaf:name       "Alice".
_:a  foaf:mbox       <mailto:alice@work.example> .

_:b  foaf:name       "Bob" .
_:b  foaf:mbox       <mailto:bob@home.example> .

此查询选择在其 foaf 资料中使用 work.example 地址的人员集合:

PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name ?mbox
WHERE {
    ?x foaf:name  ?name ;
      foaf:mbox  ?mbox .
    FILTER regex(str(?mbox), "@work\\.example$")
}

查询结果:

name mbox
"Alice" <mailto:alice@work.example>
17.4.2.8 LANG
xsd:string  LANG (literal ltrl)

如果 ltrl 具有 语言标签, 则返回它的语言标签。 如果 ltrl 没有 语言标签, 则返回空字符串。 请注意,RDF 数据模型不包含具有空 语言标签的字面量。

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

_:a  foaf:name       "Robert"@en.
_:a  foaf:name       "Roberto"@es.
_:a  foaf:mbox       <mailto:bob@work.example> .

此查询查找西班牙语 foaf:namefoaf:mbox

PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name ?mbox
WHERE {
    ?x foaf:name  ?name ;
       foaf:mbox  ?mbox .
    FILTER ( lang(?name) = "es" )
}

查询结果:

name mbox
"Roberto"@es <mailto:bob@work.example>

函数示例:

表达式 结果
LANG("abc"@en) "en"
LANG("abc"@en--ltr) "en"
LANG("abc") ""
LANG(1) ""
LANG(<http://example/>) error
17.4.2.9 LANGDIR
xsd:string  LANGDIR (literal ltrl)

如果 ltrl 具有 基方向, 则返回它的基方向。 如果 ltrl 没有 基方向, 则返回空字符串。 请注意,RDF 数据模型不包含具有空 基方向的字面量。

表达式 结果
LANGDIR("abc"@en--ltr) "ltr"
LANGDIR("abc"@en) ""
LANGDIR("abc") ""
LANGDIR(1) ""
LANGDIR(<http://example/>) error
17.4.2.10 hasLANG
xsd:string  hasLANG (RDF term term)

如果 RDF 项参数是带有 语言标签的字面量, 则返回 true。 否则,该函数返回 false

如果参数是字面量,则该函数等价于 测试该字面量的数据类型是否为 rdf:langStringrdf:dirLangString

表达式 结果
hasLANG("abc"@en) true
hasLANG("abc@"en--ltr) true
hasLANG("تصميم المواقع"@ar--rtl) true
hasLANG(1) false
hasLANG(<http://example/>) false
17.4.2.11 hasLANGDIR
xsd:string  hasLANGDIR (RDF term term)

如果 RDF 项参数是带有 基方向的字面量, 则返回 true。 否则,该函数返回 false

如果参数是字面量,则该函数等价于 测试该字面量的数据类型是否为 rdf:dirLangString

表达式 结果
hasLANGDIR("abc"@en) false
hasLANGDIR("abc@"en--ltr) true
hasLANGDIR("تصميم المواقع"@ar--rtl) true
hasLANGDIR(1) false
hasLANGDIR(<http://example/>) false
17.4.2.12 DATATYPE
iri  DATATYPE (literal literal)

返回给定字面量的 datatype IRI

具有 语言标签没有 基方向的字面量的 datatype IRIrdf:langString

具有 语言标签基方向 的字面量的 datatype IRIrdf:dirLangString

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

_:a  foaf:name       "Alice".
_:a  eg:shoeSize     "9.5"^^xsd:float .

_:b  foaf:name       "Bob".
_:b  eg:shoeSize     "42"^^xsd:integer .

此查询查找所有 shoeSize 为整数的人员的 foaf:namefoaf:shoeSize

PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX xsd:  <http://www.w3.org/2001/XMLSchema#>
PREFIX eg:   <http://biometrics.example/ns#>
SELECT ?name ?shoeSize
WHERE { 
    ?x foaf:name  ?name ;
       eg:shoeSize  ?shoeSize .
    FILTER ( datatype(?shoeSize) = xsd:integer )
}

查询结果:

name shoeSize
"Bob" 42
17.4.2.13 IRI
iri  IRI(xsd:string)
iri  IRI(iri)
iri  URI(xsd:string)
iri  URI(iri)

IRI 函数通过解析字符串参数来构造 IRI(见 [RFC3986] 和 [RFC3987],或任何取代 RFC 3986 或 RFC 3987 的后续 RFC)。该 IRI 会相对于查询的基 IRI 解析,并且必须得到一个绝对 IRI。

URI 函数是 IRI 的同义词。

如果传给该函数的是 IRI,则它原样返回该 IRI。

传入除数据类型为 xsd:string 的字面量或 IRI 之外的任何 RDF 项,都是 错误。

实现可以规范化该 IRI。

示例:

IRI("http://example/") <http://example/>
IRI(<http://example/>) <http://example/>
17.4.2.14 BNODE
blank node  BNODE()
blank node  BNODE(xsd:string)

BNODE 函数构造一个空白节点,它不同于 被查询数据集中的所有空白节点,也不同于为其他查询解调用 此构造器所创建的所有空白节点。如果使用无参数形式, 每次调用都会产生一个不同的空白节点。如果使用带有 xsd:string 字面量的形式, 则对于不同的 xsd:string 字面量,每次调用都会产生不同的空白节点;而在一个 解映射的表达式中, 使用相同 xsd:string 字面量调用时会得到同一个空白节点。

此功能与 SPARQL CONSTRUCT 模板中对 空白节点的处理兼容。

17.4.2.15 STRDT
literal  STRDT(xsd:string lexicalForm, IRI datatypeIRI)

STRDT 函数按照参数所指定的 词汇形式datatype IRI 构造一个字面量。

表达式 结果
STRDT("123", xsd:integer) "123"^^<http://www.w3.org/2001/XMLSchema#integer>
STRDT("iiii", <http://example/romanNumeral>) "iiii"^^<http://example/romanNumeral>
不应使用 datatypeIRI 参数 rdf:langStringrdf:dirLangString 调用 STRDT。若要创建以这些 IRI 作为 datatype IRI 的字面量, 应使用函数 STRLANGSTRLANGDIR
17.4.2.16 STRLANG
literal  STRLANG(xsd:string lexicalForm, xsd:string langTag)

STRLANG 函数按照参数所指定的 词汇形式语言标签 构造一个字面量, 并带有 rdf:langString 的 datatype IRI。

参数 langTag 不得为空字符串,并且应该是 有效的语言标签

表达式 结果
STRLANG("chat", "fr") "chat"@fr
STRLANG("abc", "") error
STRLANG(123, "en") error
17.4.2.17 STRLANGDIR
literal  STRLANGDIR(xsd:string lexicalForm, xsd:string langTag, xsd:string baseDirection)

STRLANGDIR 函数按照参数所指定的 词汇形式语言标签基方向 构造一个字面量, 并带有 rdf:dirLangString 的 datatype IRI。

参数 langTag 不得为空字符串,并且应该是 有效的语言标签。 参数 baseDirection 必须"ltr""rtl"

表达式 结果
STRLANGDIR("abc", "en", "ltr") "abc"@en--ltr
STRLANGDIR("abc", "en", "LTR") error
STRLANGDIR("قطة", "ar", "rtl") "قطة"@ar--rlt
STRLANGDIR("abc", "en", "") error
STRLANGDIR("abc", "", "ltr") error
STRLANGDIR(123, "", "ltr") error
STRLANGDIR(<x:uri>, "en", "ltr") error
17.4.2.18 UUID
iri  UUID()

返回来自 通用唯一标识符(UUID)URN 命名空间的全新 IRI。每次调用 UUID() 都会返回一个 不同的 UUID。它不得是 “nil” UUID(全为零)。UUID 的变体和版本 由实现决定。

UUID() <urn:uuid:b9302fb5-642e-4d3b-af19-29a8f6d894c9>
17.4.2.19 STRUUID
xsd:string  STRUUID()

返回一个字符串,即 UUID 的方案特定部分。也就是说,它作为数据类型 为 xsd:string 的字面量,是生成 UUID、转换为数据类型为 xsd:string 的字面量并移除起始 urn:uuid: 之后的结果。

STRUUID() "73cd4307-8a99-4691-a608-b5bda64fb6c1"

17.4.3 字符串上的函数

某些函数(例如 REGEXSTRLENCONTAINS) 以字符串字面量作为参数。 字符串字面量是以下之一:

  • 数据类型为 xsd:string 的字面量
  • 数据类型为 rdf:langString 且带有 语言标签的字面量
  • 数据类型为 rdf:dirLangString 且同时带有 语言标签基方向的字面量

使用任何其他 RDF 项都会导致对该函数的调用引发错误。

"abc"简单字面量 的语法缩写,表示 "abc"^^xsd:string

函数 SUBSTRSTRBEFORESTRAFTERREPLACE 返回与其第一个参数 同种类的字符串字面量

函数 CONCAT 根据参数的 字符串字面量形式返回一个字符串 字面量

函数 STRSTARTSSTRENDSCONTAINSSTRBEFORESTRAFTER 接受两个参数。这些参数必须参数兼容; 否则,调用该函数会引发错误。

如果满足以下条件,则两个字符串字面量参数是 参数 兼容的:

  • 参数是数据类型为 xsd:string 的字面量
  • 参数是数据类型为 rdf:langString 的字面量, 并具有相同的语言标签
  • 参数是数据类型为 rdf:dirLangString 的字面量, 并具有相同的 语言标签 和相同的基方向
  • 第一个参数是数据类型为 rdf:langString 的字面量, 第二个参数是数据类型为 xsd:string 的字面量
  • 第一个参数是数据类型为 rdf:dirLangString 的字面量, 第二个参数具有数据类型 xsd:string
Argument1 Argument2 兼容?
"abc" "b"
"abc"@en "b"
"abc"@en "b"@en
"abc"@fr "b"@ja
"abc" "b"@ja
"abc" "b"@en--ltr
"abc"@en--ltr "b"@en--ltr
"abc"@en--ltr "b"@en
"abc"@en--ltr "z"
17.4.3.1 STRLEN
xsd:integer  STRLEN(string literal str)

strlen 函数对应于 XPath fn:string-length 函数,并返回一个 xsd:integer,其值等于该字面量 词汇形式的字符长度。

strlen("chat") 4
strlen("chat"@en) 4
strlen("chat"@en--ltr) 4
strlen("chat"^^xsd:string) 4
17.4.3.2 SUBSTR
string literal  SUBSTR(string literal source, xsd:integer startingLoc)
string literal  SUBSTR(string literal source, xsd:integer startingLoc, xsd:integer length)

substr 函数对应于 XPath fn:substring 函数,并返回一个与 source 输入参数同种类的字面量 (数据类型为 xsd:string 的字面量、带有相同语言标签的字面量、 带有相同语言标签和基方向的字面量),但其 词汇形式 派生自源的词汇形式的子字符串。

参数 startingLoclength 可以是 xsd:integer 的派生类型。

字符串中第一个字符的索引是 1。

substr("foobar", 4) "bar"
substr("foobar"@en, 4) "bar"@en
substr("foobar"^^xsd:string, 4) "bar"^^xsd:string
substr("foobar", 4, 1) "b"
substr("foobar"@en, 4, 1) "b"@en
substr("foobar"^^xsd:string, 4, 1) "b"^^xsd:string
17.4.3.3 UCASE
string literal  UCASE(string literal str)

UCASE 函数对应于 XPath fn:upper-case 函数。它返回一个字符串字面量, 其词汇形式是参数词汇形式的大写形式。

ucase("foo") "FOO"
ucase("Foo"@en) "FOO"@en
ucase("foo"@en--ltr) "FOO"@en--ltr
ucase("foo"^^xsd:string) "FOO"^^xsd:string
17.4.3.4 LCASE
string literal  LCASE(string literal str)

LCASE 函数对应于 XPath fn:lower-case 函数。 它返回一个字符串字面量,其词汇形式是参数词汇形式的小写形式。

lcase("BAR") "bar"
lcase("Bar"@en) "bar"@en
lcase("BAR"@en--ltr) "bar"@en--ltr
lcase("BAR"^^xsd:string) "bar"^^xsd:string
17.4.3.5 STRSTARTS
xsd:boolean  STRSTARTS(string literal arg1, string literal arg2)

STRSTARTS 函数对应于 XPath fn:starts-with 函数。 参数必须参数兼容, 否则会引发错误。

对于这样的输入对,如果 arg1 的词汇形式 以 arg2 的词汇形式开头,则函数返回 true;否则返回 false。

strStarts("foobar", "foo") true
strStarts("foobar", "abc") false
strStarts("foobar"@en, "foo"@en) true
strStarts("foobar"^^xsd:string, "foo"^^xsd:string) true
strStarts("foobar"^^xsd:string, "foo") true
strStarts("foobar", "foo"^^xsd:string) true
strStarts("foobar"@en, "foo") true
strStarts("foobar"@en, "foo"^^xsd:string) true
strStarts("foobar", "foo"@en) error
17.4.3.6 STRENDS
xsd:boolean  STRENDS(string literal arg1, string literal arg2)

STRENDS 函数对应于 XPath fn:ends-with 函数。 参数必须参数兼容, 否则会引发错误。

对于这样的输入对,如果 arg1 的词汇形式 以 arg2 的词汇形式结尾,则函数返回 true;否则返回 false。

strEnds("foobar", "bar") true
strEnds("foobar", "abc") false
strEnds("foobar"@en, "bar"@en) true
strEnds("foobar"^^xsd:string, "bar"^^xsd:string) true
strEnds("foobar"^^xsd:string, "bar") true
strEnds("foobar", "bar"^^xsd:string) true
strEnds("foobar"@en, "bar") true
strEnds("foobar"@en, "bar"^^xsd:string) true
strEnds("foobar"@en, "bar"@en) error
17.4.3.7 CONTAINS
xsd:boolean  CONTAINS(string literal arg1, string literal arg2)

CONTAINS 函数对应于 XPath fn:contains。 参数必须参数兼容, 否则会引发错误。

contains("foobar", "bar") true
contains("foobar"@en, "foo"@en) true
contains("foobar"^^xsd:string, "bar"^^xsd:string) true
contains("foobar"^^xsd:string, "foo") true
contains("foobar", "bar"^^xsd:string) true
contains("foobar"@en, "foo") true
contains("foobar"@en, "bar"^^xsd:string) true
contains("foobar", "bar"@en) error
17.4.3.8 STRBEFORE
literal  STRBEFORE(string literal arg1, string literal arg2)

STRBEFORE 函数对应于 XPath fn:substring-before 函数。 参数必须参数兼容, 否则会引发错误。

对于兼容参数,如果第二个参数的词汇部分作为子字符串出现在 第一个参数的词汇部分中,则该函数返回一个与第一个参数 arg1 同种类的字面量(数据类型为 xsd:string 的字面量、带有相同语言标签的字面量)。 结果的词汇形式是 arg1 的词汇形式中, 位于 arg2 词汇形式第一次出现之前的子字符串。 如果 arg2 的词汇形式为空字符串,则认为这是匹配, 结果的词汇形式为空字符串。

如果没有这样的出现,则返回一个数据类型为 xsd:string 的 空字面量。

strBefore("abc","b") "a"
strBefore("abc"@en,"bc") "a"@en
strBefore("abc"@en,"b"@cy) error
strBefore("abc"^^xsd:string,"") ""^^xsd:string
strBefore("abc","xyz") ""
strBefore("abc"@en, "z"@en) ""
strBefore("abc"@en, "z") ""
strBefore("abc"@en, ""@en) ""@en
strBefore("abc"@en, "") ""@en
17.4.3.9 STRAFTER
literal  STRAFTER(string literal arg1, string literal arg2)

STRAFTER 函数对应于 XPath fn:substring-after 函数。 参数必须参数兼容, 否则会引发错误。

对于兼容参数,如果第二个参数的词汇部分作为子字符串出现在 第一个参数的词汇部分中,则该函数返回一个与第一个参数 arg1 同种类的字面量(数据类型为 xsd:string 的字面量、带有相同语言标签的字面量)。 结果的词汇形式是 arg1 的词汇形式中, 位于 arg2 词汇形式第一次出现之后的子字符串。 如果 arg2 的词汇形式为空字符串,则认为这是匹配, 结果的词汇形式为 arg1 的词汇形式。

如果没有这样的出现,则返回一个数据类型为 xsd:string 的 空字面量。

strAfter("abc","b") `"c"
strAfter("abc"@en,"ab") "c"@en
strAfter("abc"@en,"b"@cy) error
strAfter("abc"^^xsd:string,"") "abc"^^xsd:string
strAfter("abc","xyz") ""
strAfter("abc"@en, "z"@en) ""
strAfter("abc"@en, "z") ""
strAfter("abc"@en, ""@en) "abc"@en
strAfter("abc"@en, "") "abc"@en
17.4.3.10 CONCAT
string literal  CONCAT(string literal, ..., string literal)

CONCAT 函数接受零个或多个参数。 参数必须是字符串字面量,否则会 引发错误。

如果给出零个参数,则结果是数据类型为 xsd:string 的空字符串。

如果给出一个参数,则结果是该参数值。

如果给出两个或更多参数,则该函数返回一个 字符串字面量,使得所得 词汇形式 通过使用 fn:concat 函数连接该函数参数的 词汇形式而得到。

  • 如果所有输入字面量都是具有相同 语言标签 和相同 基方向的字面量, 则返回的字符串字面量是一个 具有数据类型 rdf:dirLangString、共同语言标签和基方向的字面量。
  • 如果所有输入字面量都是具有相同 语言标签 且没有任何参数具有 基方向的字面量, 则返回的字符串字面量是一个 具有数据类型 rdf:langString 和共同语言标签的字面量。
  • 否则,结果是数据类型为 xsd:string字符串字面量
concat("foo", "bar") "foobar"
concat("foo"@en, "bar"@en) "foobar"@en
concat("foo", "bar") "foobar"
concat("foo"@en, "bar") "foobar"
concat("foo"@en, "bar"@es) "foobar"
concat("abc") "abc"
concat("abc"@en) "abc"@en
concat() ""
17.4.3.11 langMATCHES
xsd:boolean  langMatches (xsd:string language-tag, xsd:string language-range)

如果参数 language-tag (一个语言标签) 按照 [RFC4647] 第 3.3.1 节中定义的基本过滤方案, 匹配参数 language-range (按照 [RFC4647] 第 2.1 节 语言 标签匹配基本语言范围), 则返回 true。否则,该函数返回 false

如果 language-taglanguage-range 或二者为空 (因而分别不是有效的语言标签或语言范围), 则该函数返回 false

language-range 为 "*" 时匹配任何非空的 language-tag 字符串。

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

_:a  dc:title         "That Seventies Show"@en .
_:a  dc:title         "Cette Série des Années Soixante-dix"@fr .
_:a  dc:title         "Cette Série des Années Septante"@fr-BE .
_:b  dc:title         "Il Buono, il Bruto, il Cattivo" .

此查询使用 langMatcheslang 来查找英文名为 "That Seventies Show" 的节目的法语标题:

PREFIX dc: <http://purl.org/dc/elements/1.1/>
SELECT ?title
WHERE {
    ?x dc:title  "That Seventies Show"@en ;
       dc:title  ?title .
    FILTER langMatches( lang(?title), "FR" )
}

查询结果:

title
"Cette Série des Années Soixante-dix"@fr
"Cette Série des Années Septante"@fr-BE

惯用形式 langMatches( lang( ?v ), "*" ) 不会匹配 没有语言标签的字面量,因为 lang( ?v ) 会返回空字符串,因此

PREFIX dc: <http://purl.org/dc/elements/1.1/>
SELECT ?title
WHERE {
    ?x dc:title  ?title .
    FILTER langMatches( lang(?title), "*" )
}

会报告所有带有语言标签的标题:

title
"That Seventies Show"@en
"Cette Série des Années Soixante-dix"@fr
"Cette Série des Années Septante"@fr-BE
17.4.3.12 REGEX
xsd:boolean  REGEX (string literal text, xsd:string pattern)
xsd:boolean  REGEX (string literal text, xsd:string pattern, xsd:string flags)

调用 XPath fn:matches 函数,以将 text 与正则表达式 pattern 进行匹配。正则 表达式语言定义于 XQuery 1.0 and XPath 2.0 Functions and Operators 第 7.6.1 正则 表达式语法节 [XPATH-FUNCTIONS-31]。

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

_:a  foaf:name       "Alice".
_:b  foaf:name       "Bob" .
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name
WHERE { 
    ?x foaf:name  ?name
    FILTER regex(?name, "^ali", "i")
}

查询结果:

name
"Alice"
17.4.3.13 REPLACE
string literal  REPLACE (string literal arg, xsd:string pattern, xsd:string replacement )
string literal  REPLACE (string literal arg, xsd:string pattern, xsd:string replacement,  xsd:string flags)

REPLACE 函数对应于 XPath fn:replace 函数。它把正则表达式 pattern 的每个非重叠出现替换为替换字符串。 正则表达式匹配可能涉及修饰符标志。见 REGEX

replace("abcd", "b", "Z") "aZcd"
replace("abab", "B", "Z","i") "aZaZ"
replace("abab", "B.", "Z","i") "aZb"
17.4.3.14 ENCODE_FOR_URI
xsd:string  ENCODE_FOR_URI(string literal ltrl)

ENCODE_FOR_URI 函数对应于 XPath fn:encode-for-uri 函数。它返回一个 数据类型为 xsd:string 的字面量,其词汇形式是根据 fn:encode-for-uri 函数转换保留字符后,从输入的词汇形式得到的。

encode_for_uri("Los Angeles") "Los%20Angeles"
encode_for_uri("Los Angeles"@en) "Los%20Angeles"
encode_for_uri("Los Angeles"^^xsd:string) "Los%20Angeles"

17.4.4 数值上的函数

17.4.4.1 ABS
numeric  ABS (numeric term)

返回 arg 的绝对值。如果 arg 不是数值,则引发错误。

对于具有来自 XDM 的数据类型的项, 此函数与 fn:abs 相同。

ABS(1) 1
ABS(-1.5) 1.5
17.4.4.2 ROUND
numeric  ROUND (numeric term)

返回最接近该参数且不含小数部分的数字。如果有两个这样的数字, 则返回最接近正无穷的那个。如果 arg 不是数值, 则引发错误。

对于具有来自 XDM 的数据类型的项,此函数与 fn:round 相同。

ROUND(2.4999) 2.0
ROUND(2.5) 3.0
ROUND(-2.5) -2.0
17.4.4.3 CEIL
numeric  CEIL (numeric term)

返回不小于 arg 值且没有小数部分的最小 (最接近负无穷的)数字。如果 arg 不是数值,则引发错误。

对于具有来自 XDM 的数据类型的项, 此函数与 fn:ceiling 相同。

CEIL(10.5) 11.0
CEIL(-10.5) -10.0
17.4.4.4 FLOOR
numeric  FLOOR (numeric term)

返回不大于 arg 值且没有小数部分的最大 (最接近正无穷的)数字。如果 arg 不是数值,则引发错误。

对于具有来自 XDM 的数据类型的项, 此函数与 fn:floor 相同。

FLOOR(10.5) 10.0
FLOOR(-10.5) -11.0
17.4.4.5 RAND
xsd:double  RAND ( )

返回一个介于 0(含)和 1.0e0(不含)之间的伪随机数。 每次调用此函数都可能产生不同的数字。数字应以近似相等的概率产生。

rand() "0.31221030831984886"^^xsd:double

17.4.5 日期和时间上的函数

17.4.5.1 NOW
xsd:dateTime  NOW ()

返回当前查询执行的 XSD dateTime 值。在任一次查询执行中, 对此函数的所有调用都必须返回相同的值。返回的确切时刻未指定。

NOW() "2011-01-10T14:45:13.815-05:00"^^xsd:dateTime
17.4.5.2 YEAR
xsd:integer  YEAR (xsd:dateTime arg)

以整数形式返回 arg 的年份部分。

此函数对应于 fn:year-from-dateTime

YEAR("2011-01-10T14:45:13.815-05:00"^^xsd:dateTime) 2011
17.4.5.3 MONTH
xsd:integer  MONTH (xsd:dateTime arg)

以整数形式返回 arg 的月份部分。

此函数对应于 fn:month-from-dateTime

MONTH("2011-01-10T14:45:13.815-05:00"^^xsd:dateTime) 1
17.4.5.4 DAY
xsd:integer  DAY (xsd:dateTime arg)

以整数形式返回 arg 的日部分。

此函数对应于 fn:day-from-dateTime

day("2011-01-10T14:45:13.815-05:00"^^xsd:dateTime) 10
17.4.5.5 HOURS
xsd:integer  HOURS (xsd:dateTime arg)

以整数形式返回 arg 的小时部分。该值与 XSD dateTime 的词汇形式中给出的值一致。

此函数对应于 fn:hours-from-dateTime

HOURS("2011-01-10T14:45:13.815-05:00"^^xsd:dateTime) 14
17.4.5.6 MINUTES
xsd:integer  MINUTES (xsd:dateTime arg)

返回 arg 词汇形式中的分钟部分。该值与 XSD dateTime 的词汇形式中给出的值一致。

此函数对应于 fn:minutes-from-dateTime

MINUTES("2011-01-10T14:45:13.815-05:00"^^xsd:dateTime) 45
17.4.5.7 SECONDS
xsd:decimal  SECONDS (xsd:dateTime arg)

返回 arg 词汇形式中的秒部分。

此函数对应于 fn:seconds-from-dateTime

SECONDS("2011-01-10T14:45:13.815-05:00"^^xsd:dateTime) 13.815
17.4.5.8 TIMEZONE
xsd:dayTimeDuration  TIMEZONE (xsd:dateTime arg)

以 xsd:dayTimeDuration 形式返回 arg 的时区部分。 如果没有时区,则引发错误。

此函数对应于 fn:timezone-from-dateTime, 但对没有时区的字面量的处理除外。

TIMEZONE("2011-01-10T14:45:13.815-05:00"^^xsd:dateTime) "-PT5H"^^xsd:dayTimeDuration
TIMEZONE("2011-01-10T14:45:13.815Z"^^xsd:dateTime) "PT0S"^^xsd:dayTimeDuration
TIMEZONE("2011-01-10T14:45:13.815"^^xsd:dateTime) error
17.4.5.9 TZ
xsd:string  TZ (xsd:dateTime arg)

以数据类型为 xsd:string 的字面量形式返回 arg 的时区部分。 如果没有时区,则返回空字符串。

TZ("2011-01-10T14:45:13.815-05:00"^^xsd:dateTime) "-05:00"
TZ("2011-01-10T14:45:13.815Z"^^xsd:dateTime) "Z"
TZ("2011-01-10T14:45:13.815"^^xsd:dateTime) ""

17.4.6 三元组项上的函数

17.4.6.1 TRIPLE
triple term  TRIPLE (RDF term subj, RDF term pred, RDF term obj)
<<( subj pred obj )>>

如果三元组组(subjpredobj) 是一个 RDF 三元组 (也就是说,subjIRIblank nodepredIRI; 并且 objIRItriple termblank nodeliteral), 则该函数返回一个具有这三个元素的三元组项。 否则,该函数引发错误。

作为简写记法,TRIPLE 函数 也可以使用 <<()>>, 以三元组项表达式的形式书写。 这种简写形式有语法限制:

  • 三元组项表达式的三个元素中的每一个都只能是 变量 或直接写出的 RDF 项,而不能是任意表达式。
  • 主语和谓语位置的语法限于 IRI变量

函数形式 TRIPLE 可以与任意表达式一起使用。

VERSION "1.2"
PREFIX : <http://example/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

SELECT ?s ?date {
    ?s ?p ?o .
    BIND( <<( ?s ?p ?o )>> AS ?tt )
    :myreifier rdf:reifies ?tt .
    :myreifier :tripleAdded ?date .
}
VERSION "1.2"
PREFIX : <http://example/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

SELECT ?s ?date {
    ?s ?p ?o .
    BIND( TRIPLE(?s, ?p, ?o) AS ?tt )
    :myreifier rdf:reifies ?tt .
    :myreifier :tripleAdded ?date .
}
17.4.6.2 SUBJECT
RDF term  SUBJECT (triple term triple-term)

如果参数是一个 triple term, 该函数返回该三元组项的 subject。 如果参数不是 triple term, 则引发错误。

17.4.6.3 PREDICATE
RDF term  PREDICATE (triple term triple-term)

如果参数是一个 triple term, 该函数返回该三元组项的 predicate。 如果参数不是 triple term, 则引发错误。

17.4.6.4 OBJECT
RDF term  OBJECT (triple term triple-term)

如果参数是一个 triple term, 该函数返回该三元组项的 object。 如果参数不是 triple term, 则引发错误。

17.4.6.5 isTRIPLE
xsd:boolean  isTRIPLE (RDF term term)

如果参数是一个triple term, 该函数返回 true。 如果参数是任何其他种类的 RDF 项, 该函数返回 false。

17.4.7 哈希函数

17.4.7.1 MD5
xsd:string  MD5 (xsd:string arg)

返回根据 xsd:string 的词汇形式计算出的 MD5 校验和, 表示为十六进制数字字符串。十六进制数字应该为小写。

MD5("abc") "900150983cd24fb0d6963f7d28e17f72"
17.4.7.2 SHA1
xsd:string  SHA1 (xsd:string arg)

返回根据 xsd:string 的词汇形式计算出的 SHA1 校验和, 表示为十六进制数字字符串。十六进制数字应该为小写。

SHA1("abc") "a9993e364706816aba3e25717850c26c9cd0d89d"
17.4.7.3 SHA256
xsd:string  SHA256 (xsd:string arg)

返回根据 xsd:string 的词汇形式计算出的 SHA256 校验和, 表示为十六进制数字字符串。十六进制数字应该为小写。

SHA256("abc") "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
17.4.7.4 SHA384
xsd:string  SHA384 (xsd:string arg)

返回根据 xsd:string 的词汇形式计算出的 SHA384 校验和, 表示为十六进制数字字符串。十六进制数字应该为小写。

SHA384("abc") "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7"
17.4.7.5 SHA512
xsd:string  SHA512 (xsd:string arg)

返回根据 xsd:string 的词汇形式计算出的 SHA512 校验和, 表示为十六进制数字字符串。十六进制数字应该为小写。

SHA512("abc") "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"

17.5 XPath 构造器函数

SPARQL 导入了 XPath 和 XQuery 函数与运算符 3.1 [XPATH-FUNCTIONS-31] 第 19.1 从 原始类型到原始类型的转换中定义的一部分 XPath 构造器函数。 SPARQL 构造器包括适用于 SPARQL 操作数数据类型的所有 XPath 构造器,以及 RDF 数据模型所施加的 附加数据类型。 SPARQL 中的转换通过在源类型操作数上调用目标类型的构造器函数来执行。

XPath 只定义了从一种 XML Schema 数据类型到另一种数据类型的转换。其余转换 定义如下:

下表概述始终允许(Y)、 从不允许(N)以及依赖于词汇 值(M)的转换操作。例如,从 xsd:string(第一行)到 xsd:float(第二列)的转换操作 依赖于词汇值(M)。

bool = xsd:boolean
dbl = xsd:double
flt = xsd:float
dec = xsd:decimal
int = xsd:integer
dT = xsd:dateTime
str = xsd:string
IRI = IRI

From \ To str flt dbl dec int dT bool
str Y M M M M M M
flt Y Y Y M M N Y
dbl Y Y Y M M N Y
dec Y Y Y Y Y N Y
int Y Y Y Y Y N Y
dT Y N N N N Y N
bool Y Y Y Y Y N Y
IRI Y N N N N N N

17.6 可扩展值测试

应注意,任何被指定为在某些条件下返回错误的函数或运算符, 都是有效的扩展点。也就是说,实现可以在这些错误情形中返回 非错误值,并且仍然符合本推荐标准。

PrimaryExpression 文法规则可以是对由 IRI 命名的扩展函数的调用。扩展函数接受若干 RDF 项作为参数,并返回一个 RDF 项。 这些函数的语义由标识该函数的 IRI 标识。

使用扩展函数的 SPARQL 查询可能具有有限的互操作性。

例如,考虑一个名为 func:even 的函数:

xsd:boolean   func:even (numeric value)

此函数可在 FILTER 中按如下方式调用:

PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX func: <http://example.org/functions#>
SELECT ?name ?id
WHERE { 
    ?x foaf:name  ?name ;
       func:empId   ?id .
    FILTER (func:even(?id))
}

再举第二个例子,考虑一个计算两点之间距离的函数 aGeo:distance,此处用它查找 Grenoble 附近的地点:

xsd:double   aGeo:distance (numeric x1, numeric y1, numeric x2, numeric y2)
PREFIX aGeo: <http://example.org/geo#>

SELECT ?neighbor
WHERE {
    ?a aGeo:placeName "Grenoble" .
    ?a aGeo:locationX ?axLoc .
    ?a aGeo:locationY ?ayLoc .

    ?b aGeo:placeName ?neighbor .
    ?b aGeo:locationX ?bxLoc .
    ?b aGeo:locationY ?byLoc .

    FILTER ( aGeo:distance(?axLoc, ?ayLoc, ?bxLoc, ?byLoc) < 10 ) .
}

扩展函数可能用于测试核心 SPARQL 规范不支持的某种应用数据类型; 它也可能是在数据类型格式之间进行转换,例如从另一种日期格式 转换为 XSD dateTime RDF 项。

18. SPARQL의 정의

이 절은 질의 문자열과 RDF 데이터셋이 주어졌을 때 그래프 패턴과 해 수정자의 평가에 대한 올바른 동작을 정의합니다. 이는 SPARQL 구현이 여기에서 정의한 과정을 사용해야 함을 의미하지 않습니다.

SPARQL 질의를 실행한 결과는 SPARQL 질의를 문자열로 시작하여, 그 문자열을 추상 구문 형식으로 바꾸고, 다시 그 추상 구문을 SPARQL 대수의 연산자들로 이루어진 SPARQL 추상 질의로 바꾸는 일련의 단계로 정의됩니다. 그런 다음 이 추상 질의는 RDF 데이터셋에서 평가됩니다.

18.1 초기 정의

18.1.1 RDF 데이터셋

RDF 데이터셋의 개념은 [RDF12-CONCEPTS]에 정의되어 있습니다.

다음 정의를 위해, 각 RDF 데이터셋을 하나의 집합으로 포착합니다.

{ G, (<u1>, G1), (<u2>, G2), ... (<un>, Gn) } 여기서 G와 각 Gi는 그래프이고, 각 <ui>는 IRI 또는 빈 노드입니다. 각 <ui>는 서로 구별됩니다.

G는 기본 그래프라고 부릅니다. (<ui>, Gi)는 명명된 그래프라고 부릅니다.

정의: 활성 그래프

활성 그래프는 기본 그래프 패턴 일치에 사용되는 데이터셋의 그래프입니다.

18.1.2 질의 변수

정의: 질의 변수

모든 RDF 용어의 집합과 서로소인, 가산 무한 집합 V가 있다고 가정합니다. 이 집합 V의 모든 원소는 질의 변수입니다.

18.1.3 트리플 패턴

정의: 트리플 패턴

트리플 패턴은 다음과 같이 귀납적으로 정의되는 3-튜플입니다. 만약

(s, p, o)는 트리플 패턴입니다.

트리플 패턴은 순환을 허용하지 않습니다 (즉, 트리플 패턴은 자기 자신 안에 포함될 수 없습니다).

참고

트리플 패턴에 대한 이 정의에는 리터럴 주어가 포함됩니다. 이는 RDF-core에 의해 지적된 바 있습니다.

"[RDF core Working Group]은 리터럴이 주어가 되어서는 안 되는 이유를 알지 못하며, 더 덜 제한적인 헌장을 가진 향후 WG가 문장의 주어로 리터럴을 허용하도록 구문을 확장할 수 있음을 인지하고 있다고 언급했습니다."

RDF 그래프는 리터럴 주어를 포함할 수 없으므로, 주어가 리터럴인 모든 SPARQL 트리플 패턴은 어떤 RDF 그래프에서도 일치하지 않습니다.

참고

주어 위치에 다른 트리플 패턴을 가진 트리플 패턴은 어떤 RDF 그래프에서도 일치하지 않습니다. 이는 RDF 트리플이 그 주어 위치에 트리플 용어를 가질 수 없기 때문입니다.

18.1.4 기본 그래프 패턴

정의: 기본 그래프 패턴

기본 그래프 패턴트리플 패턴들의 집합입니다.

빈 그래프 패턴은 빈 집합인 기본 그래프 패턴입니다.

18.1.5 속성 경로 패턴

정의: 속성 경로

속성 경로는 시퀀스 ST 안의 트리플 ti들의 시퀀스이며, n = length(ST)-1이고, i=0부터 n까지 ti의 객체가 ti+1의 주어와 같은 용어인 경우입니다.

t0의 주어를 경로의 시작이라고 부릅니다.

tn의 객체를 경로의 끝이라고 부릅니다.

각 ti가 G의 트리플이면, 속성 경로는 그래프 G 안의 경로입니다.

속성 경로는 데이터셋 안의 여러 그래프에 걸치지 않습니다.

정의: 속성 경로 표현식

속성 경로 표현식은 위에서 설명한 속성 경로 형식을 사용하는 표현식입니다.

정의: 속성 경로 패턴

속성 경로 패턴은 다음을 만족하는 3-튜플 (s, p, o)입니다.

속성 경로 패턴은 술어 위치에 속성 경로 표현식을 포함하도록 트리플 패턴을 일반화한 것입니다.

18.1.6 해 매핑

해 매핑은 변수 집합에서 RDF 용어 집합으로의 매핑입니다. 명확한 경우에는 '해'라는 용어를 사용합니다.

정의: 해 매핑

해 매핑 μ는 부분 함수 μ : VT이며, 여기서 V는 모든 변수의 집합이고 T는 모든 RDF 용어의 집합입니다.

μ의 정의역은 dom(μ)로 표시하며, μ가 정의된 V의 부분집합입니다.

정의: 해 시퀀스

해 시퀀스는 해들의 목록이며, 순서가 없을 수도 있습니다.

μ가 제공하는 변수의 용어를 사용하여 표현식 expr의 값을 expr(μ)로 씁니다. 평가는 오류가 될 수 있습니다.

18.1.7 해 시퀀스 수정자

정의: 해 시퀀스 수정자

해 시퀀스 수정자는 다음 중 하나입니다.

  • Order By 수정자: 해를 순서대로 배치
  • Projection 수정자: 특정 변수를 선택
  • Distinct 수정자: 시퀀스 안의 해가 고유하도록 보장
  • Reduced 수정자: 구별되지 않는 해가 제거될 수 있도록 허용
  • Offset 수정자: 전체 해 시퀀스에서 해가 시작되는 위치를 제어
  • Limit 수정자: 해의 수를 제한

18.1.8 SPARQL 질의

정의: SPARQL 질의

SPARQL 추상 질의는 튜플 (E, DS, QF)이며, 여기서:

정의: 질의 수준

질의 수준은 그래프 패턴, 그룹화와 집계의 집합, 그리고 해 수정자의 집합입니다.

질의는 "질의 수준"들의 트리이며, 각 하위 질의는 그 트리 안에서 하나의 질의 수준을 형성합니다.

18.2 대수 구문

SPARQL 질의의 평가 의미론을 정의하기 위해, SPARQL 질의 문자열의 추상 구문 트리 (SPARQL 문법에 의해 정의됨)는 먼저 SPARQL 대수와 유사한 구문으로 변환됩니다. 이 절은 이 대수 구문에서 형성될 수 있는 표현식을 정의하고, 그런 다음 SPARQL 질의 문자열을 이 대수 구문으로 변환하는 방법을 18.3 대수 구문으로의 변환 절에서 정의합니다.

대수 질의 표현식은 다음과 같이 재귀적으로 정의됩니다.

앞의 정의에서 사용된 대수 속성 경로 표현식의 개념은 다음과 같이 재귀적으로 정의됩니다.

18.3 대수 구문으로의 변환

이 절은 SPARQL 질의 문자열 안의 그래프 패턴과 해 수정자를 대수 질의 표현식으로 변환하는 과정을 정의합니다. 설명된 과정은 중첩된 SELECT 구문을 사용하는 하위 질의가 형성하는 하나의 질의 중첩 수준을 변환하며, 하위 질의에 재귀적으로 적용됩니다. 각 수준은 그래프 패턴 일치와 필터링으로 이루어지고, 그 뒤에 해 수정자가 적용됩니다.

SPARQL 질의 문자열은 파싱되고, 4. SPARQL 구문 절에 제공된 IRI와 트리플 패턴에 대한 축약이 적용됩니다. 이 시점에서 추상 구문 트리는 다음으로 구성됩니다.

패턴 수정자 질의 형식 기타
RDF 용어 DISTINCT SELECT VALUES
속성 경로 표현식 REDUCED CONSTRUCT SERVICE
속성 경로 패턴 투영 DESCRIBE  
그룹 ORDER BY ASK  
OPTIONAL LIMIT    
UNION OFFSET    
GRAPH Select 표현식    
BIND      
GROUP BY      
HAVING      
MINUS      
FILTER      

18.3.1 변수 범위

질의의 대수 표현식을 평가하는 그 지점에서 어떤 변수가 해 매핑의 정의역 안에 있을 수 있는 방법이 있다면, 그 변수를 범위 안에 있음으로 정의합니다. 아래 정의는 질의의 추상 구문 트리로부터 이를 결정하는 방법을 제공합니다.

투영을 가진 하위 질의는 변수를 숨길 수 있음에 유의하십시오. FILTER 안이나 MINUS 안에서 변수를 사용해도 그 변수는 해당 형식 바깥에서 범위 안에 있게 되지 않습니다.

P, P1, P2를 그래프 패턴이라고 하고, E, E1,..., En을 표현식이라고 합시다. 변수 v는 다음 경우 범위 안에 있습니다.

구문 형식 범위 안의 변수
Basic Graph Pattern (BGP) v가 BGP 안에 나타남
Path v가 경로 안에 나타남
GroupGraphPattern { P1 P2 ... } v가 P1, P2, ... 중 하나 이상에서 범위 안에 있으면 v는 범위 안에 있음
GRAPH X { P } X가 변수 v이거나 v가 P에서 범위 안에 있음
{ P1 } UNION { P2 } v가 P1에서 범위 안에 있거나 P2에서 범위 안에 있음
OPTIONAL {P} v가 P에서 범위 안에 있음
SERVICE X {P} X가 변수 v이거나 v가 P에서 범위 안에 있음
BIND (expr AS v) v가 범위 안에 있음
SELECT .. v .. { P } v가 범위 안에 있음
SELECT ... (expr AS v) v가 범위 안에 있음
GROUP BY ... v v가 범위 안에 있음
GROUP BY ... (expr AS v) v가 범위 안에 있음
SELECT * { P } vP 안에서 범위 안에 있음
VALUES v { values } v가 범위 안에 있음
VALUES varlist { values } vvarlist 안에 있으면 v는 범위 안에 있음

변수 v(expr AS v) 형식이 나타나는 지점에서 범위 안에 있어서는 안 됩니다. (expr AS v)에 대한 범위 지정은 SELECT 표현식에서 즉시 적용됩니다.

BIND (expr AS v)에서는 변수 v가 그것이 사용되는 그룹 그래프 패턴 안의 선행 요소들로부터 범위 안에 있지 않아야 합니다.

SELECT에서, 변수 vSELECT 절의 그래프 패턴 안에서 범위 안에 있어서는 안 되며, 같은 절의 앞선 select 표현식에서 이미 사용되어서도 안 됩니다.

18.3.2 그래프 패턴 변환

이 절은 SPARQL 그래프 패턴을 대수 질의 표현식으로 변환하는 과정을 설명합니다. 이 과정은 질의의 WHERE 절을 형성하는 그룹 그래프 패턴 (중괄호("{ }") 구분자 사이의 단위)에 적용되고, 그룹 그래프 패턴 안의 각 구문 요소에 재귀적으로 적용됩니다. 변환 결과는 대수 질의 표현식입니다.

요약하면, 단계는 다음과 같이 적용됩니다.

여기서 설명한 그래프 패턴 변환 알고리즘을

translate(graph pattern)

라고 씁니다.

작업 그룹은 SPARQL 1.0에서 단순화 단계가 적용되는 지점이, optional 안에 이중으로 중첩된 필터와 패턴을 포함하는 질의의 변환을 모호하게 만든다고 지적합니다.
OPTIONAL { { ... FILTER ( ... ?x ... ) } }..

이는 두 개의 비규범 테스트 케이스로 설명됩니다.

모든 그래프 패턴 변환 뒤에 단순화 단계를 적용하는 해석이 선호됩니다.

18.3.2.1 구문 형식 확장

4. SPARQL 구문 절에 제공된 IRI와 트리플 패턴에 대한 축약을 확장합니다.

18.3.2.2 FILTER 요소 수집

FILTER 표현식은 그것이 나타나는 전체 그룹 그래프 패턴에 적용됩니다. 필터링을 수행하는 대수 연산자는 각 그룹 요소를 변환한 뒤 그룹에 추가됩니다. 여기서는 필터를 함께 수집하고 그룹에서 제거한 다음, 변환된 전체 그룹 그래프 패턴에 적용합니다.

Let FS := empty set
For each form FILTER(expr) in the group graph pattern
    FS := FS ∪ {expr}
    End

필터 표현식 집합 FS나중에 사용됩니다.

18.3.2.3 속성 경로 표현식 변환

다음 표는 SPARQL 질의 문자열 안의 속성 경로 표현식대수 속성 경로 표현식으로 변환하는 방법을 제공합니다. 이는 속성 경로 표현식의 모든 요소에 재귀적으로 적용됩니다.

이 단계 다음의 단계는 특정 형식을 트리플 패턴으로 변환하며, 이들은 나중에 인접성에 의해 (중간 그룹 패턴 구분자 {}) 또는 다른 구문 형식 없이) 기본 그래프 패턴으로 변환됩니다. 전체적으로, 단순히 IRI인 SPARQL 구문 속성 경로는 트리플 패턴이 되며, 이들은 기본 그래프 패턴으로 집계됩니다.

참고:

  • 부정 속성 집합(NPS) 안에서 IRI와 ^IRI 형식의 순서는 관련이 없습니다.
구문 형식 (path) 대수 형식 (path)
iri Link(iri)
^path Inv(path)
!(:iri1|...|:irin) NPS({:iri1 ... :irin})
!(^:iri1|...|^:irin) Inv( NPS({:iri1 ... :irin}) )
!(:iri1|...|:irii|^:irii+1|...|^:irim)  Alt( NPS({:iri1 ...:irii}),
    Inv(NPS({:irii+1, ..., :irim})) )
path1 / path2 Seq(path1, path2)
path1 | path2 Alt(path1, path2)
path* ZeroOrMorePath(path)
path+ OneOrMorePath(path)
path? ZeroOrOnePath(path)
18.3.2.4 속성 경로 패턴 변환

앞 단계는 속성 경로 표현식을 변환했습니다. 이 단계는 주어 끝점, 속성 경로 표현식, 객체 끝점으로 이루어진 속성 경로 패턴을 변환합니다. 이 단계는 속성 경로 패턴의 속성 경로 표현식이 이미 대수 속성 경로 표현식의 형식으로 주어졌다고 가정합니다. 이 단계의 결과는 트리플 패턴 및 대수 질의 표현식 Path(...) 형식일 수 있습니다.

참고:

  • xyRDF 용어 또는 변수입니다.
  • var는 새로운 변수입니다.
  • ppe, ppe1, ppe2대수 속성 경로 표현식입니다.
  • 이들은 속성 경로 표현식 내부가 아니라 속성 경로 패턴에만 적용됩니다.
  • 표에서 앞쪽에 있는 변환은 마지막 변환보다 우선하여 적용됩니다.
  • 최종 변환은 남아 있는 모든 속성 경로 표현식을 공통 형식 Path(...)로 감쌉니다.
대수 형식 (path) 변환
x Link(iri) y x iri y
x Inv(iri) y y iri x
x Seq(ppe1, ppe2) y x ppe1 var . var ppe2 y
x ppe y Path(x, ppe, y)
Issue 226: 속성 경로 패턴의 변환이 불완전함 spec:bug
이 표의 변환 규칙은 재귀적으로 적용되도록 의도된 것으로 보이지만, 이 절은 이에 대해 아무것도 말하지 않습니다. 특히 "x Seq(ppe1, ppe2) y"의 경우, 결과 변환 안의 ppe1ppe2는 여전히 임의의 대수 속성 경로 표현식일 수 있으므로, 두 결과 속성 경로 패턴 각각 ("x ppe1 var" 및 "var ppe2 y")에 대해 변환이 다시 적용되어야 합니다.

전체 경로 변환 과정의 예(?_V는 새로운 변수):

?s :p/:q ?o
?s :p ?_V .
?_V :q ?o
?s :p* ?o
Path(?s, ZeroOrMorePath(Link(:p)), ?o)
:list rdf:rest*/rdf:first ?member
Path(:list, ZeroOrMorePath(Link(rdf:rest)), ?_V) .
?_V rdf:first ?member
18.3.2.5 기본 그래프 패턴 변환

속성 경로를 변환한 뒤, 인접한 모든 트리플 패턴은 함께 수집되어 기본 그래프 패턴 BGP(triples)를 형성합니다.

18.3.2.6 그래프 패턴 변환

다음으로, 남아 있는 각 그래프 패턴 형식을 변환하며, 변환 과정을 재귀적으로 적용합니다.

형식이 GroupOrUnionGraphPattern인 경우

Let A := undefined
          
For each element G in the GroupOrUnionGraphPattern
    If A is undefined
        A := Translate(G)
    Else
        A := Union(A, Translate(G))
    End

The result is A

형식이 GraphGraphPattern인 경우

If the form is GRAPH IRI GroupGraphPattern
    The result is Graph(IRI, Translate(GroupGraphPattern))
If the form is GRAPH Var GroupGraphPattern
    The result is Graph(Var, Translate(GroupGraphPattern))

형식이 GroupGraphPattern인 경우:

Let G := ContextSolution

For each element E in the sequence of elements in the GroupGraphPattern

    If E is of the form OPTIONAL{P} 
        Let A := Translate(P)
        If A is of the form Filter(F, A2)
            G := LeftJoin(G, A2, F)
        Else 
            G := LeftJoin(G, A, true)
            End
        End

    If E is of the form MINUS{P}
        G := Minus(G, Translate(P))
        End

    If E is of the form BIND(expr AS var)
        G := Extend(G, var, expr)
        End

    If E is any other form 
        Let A := Translate(E)
        G := Join(G, A)
        End

   End
   
The result is G.

형식이 InlineData인 경우

The result is a multiset data of solution mappings.
data는 변수 목록(또는 단일 변수)의 대응 위치에 있는 변수로부터 해 매핑을 형성하여 만들어지며, DataBlockValueUNDEF라는 단어이면 해당 바인딩을 생략합니다.

형식이 SubSelect인 경우

The result is ToMultiset(Translate(SubSelect))
18.3.2.7 그룹의 필터

그룹이 변환된 뒤, 필터 표현식은 그룹의 나머지 전체에 적용되도록 추가됩니다.

If FS is not empty
    Let G := output of preceding step
    Let X := Conjunction of expressions in FS
    G := Filter(X, G)
End
18.3.2.8 단순화 단계

하나의 그래프 패턴으로 이루어진 일부 그룹은 Join(Z, A)가 되는데, 여기서 Z는 빈 기본 그래프 패턴(빈 집합)입니다. 이들은 A로 대체됩니다. 빈 그래프 패턴 Z는 join의 항등원입니다.

Replace Join(Z, A) by A
Replace Join(A, Z) by A

18.3.3 매핑된 그래프 패턴의 예

다시쓰기 예의 두 번째 형식은 첫 번째 형식에서 단순화 단계에 의해 빈 그룹 join이 제거된 것입니다. Z는 빈 기본 그래프 패턴입니다.

예: 단일 트리플 패턴으로 이루어진 기본 그래프 패턴을 가진 그룹:

{ ?s ?p ?o }
Join(Z, BGP(?s ?p ?o) )
BGP(?s ?p ?o)

예: 두 개의 트리플 패턴으로 이루어진 기본 그래프 패턴을 가진 그룹:

{ ?s :p1 ?v1 ; :p2 ?v2 }
BGP( ?s :p1 ?v1 . ?s :p2 ?v2 )
Issue 246: 그래프 패턴 변환 예가 일관되지 않음 spec:editorial
위 예는 단순화 단계 이전의 결과 표현식 버전을 포함하지 않습니다. 아래 여러 다른 예도 마찬가지입니다. 예들은 이 점에서 일관되어야 합니다.

예: 두 기본 그래프 패턴의 union으로 이루어진 그룹:

{ { ?s :p1 ?v1 } UNION {?s :p2 ?v2 } }
Union(Join(Z, BGP(?s :p1 ?v1)),
      Join(Z, BGP(?s :p2 ?v2)) )
Union( BGP(?s :p1 ?v1) , BGP(?s :p2 ?v2) )

예: union과 기본 그래프 패턴의 union으로 이루어진 그룹:

{ { ?s :p1 ?v1 } UNION {?s :p2 ?v2 } UNION {?s :p3 ?v3 } }
Union(
    Union( Join(Z, BGP(?s :p1 ?v1)),
           Join(Z, BGP(?s :p2 ?v2))) ,
    Join(Z, BGP(?s :p3 ?v3)) )
Union(
    Union( BGP(?s :p1 ?v1) ,
           BGP(?s :p2 ?v2),
    BGP(?s :p3 ?v3))

예: 기본 그래프 패턴과 optional 그래프 패턴으로 이루어진 그룹:

{ ?s :p1 ?v1 OPTIONAL {?s :p2 ?v2 } }
LeftJoin(
    Join(Z, BGP(?s :p1 ?v1)),
    Join(Z, BGP(?s :p2 ?v2)),
    true)
LeftJoin(BGP(?s :p1 ?v1), BGP(?s :p2 ?v2), true)

예: 기본 그래프 패턴과 두 개의 optional 그래프 패턴으로 이루어진 그룹:

{ ?s :p1 ?v1 OPTIONAL {?s :p2 ?v2 } OPTIONAL { ?s :p3 ?v3 } }
LeftJoin(
    LeftJoin(
        BGP(?s :p1 ?v1),
        BGP(?s :p2 ?v2),
        true) ,
    BGP(?s :p3 ?v3),
    true)

예: 기본 그래프 패턴과 필터가 있는 optional 그래프 패턴으로 이루어진 그룹:

{ ?s :p1 ?v1 OPTIONAL {?s :p2 ?v2 FILTER(?v1<3) } }
LeftJoin(
     Join(Z, BGP(?s :p1 ?v1)),
     Join(Z, BGP(?s :p2 ?v2)),
     (?v1<3) )
LeftJoin(
    BGP(?s :p1 ?v1) ,
    BGP(?s :p2 ?v2) ,
   (?v1<3) )

예: union 그래프 패턴과 optional 그래프 패턴으로 이루어진 그룹:

{ {?s :p1 ?v1} UNION {?s :p2 ?v2} OPTIONAL {?s :p3 ?v3} }
LeftJoin(
  Union(BGP(?s :p1 ?v1),
        BGP(?s :p2 ?v2)) ,
  BGP(?s :p3 ?v3) ,
  true )

예: 기본 그래프 패턴, 필터 및 optional 그래프 패턴으로 이루어진 그룹:

{ ?s :p1 ?v1 FILTER (?v1 < 3 ) OPTIONAL {?s :p2 ?v2} }
Filter( ?v1 < 3 ,
  LeftJoin( BGP(?s :p1 ?v1), BGP(?s :p2 ?v2), true) ,
  )

예: BIND를 포함하는 패턴:

{ ?s :p ?v . BIND (2*?v AS ?v2) ?s :p1 ?v2 }
Join(
   Extend( BGP(?s :p ?v), ?v2, 2*?v) ,
   BGP(?s :p1 ?v2) )

예: 단순화 단계가 있는 BIND 포함 패턴:

Issue 246: 그래프 패턴 변환 예가 일관되지 않음 spec:editorial
다음 예는 결과 표현식의 첫 번째 버전(단순화 단계 이전)을 나타내기 위해 {}를 사용하는 반면, 위의 이전 예들은 대신 Z를 사용합니다. 예들은 이 점에서 일관되어야 합니다.
{ ?s :p ?v . {} BIND (2*?v AS ?v2) }
Extend(
   Join(
     Join( {}, BGP(?s :p ?v)),
     {}),
   ?v2, 2*?v
)
Extend(
   BGP(?s :p ?v) ,
   ?v2, 2*?v
)

예: MINUS를 포함하는 패턴:

{ ?s :p ?v . MINUS {?s :p1 ?v2 } }
Minus(
   BGP(?s :p ?v) ,
   BGP(?s :p1 ?v2)
)

예: 하위 질의를 포함하는 패턴:

{ ?s :p ?o . {SELECT DISTINCT ?o {?o ?p ?z} } }
Join(
   BGP(?s :p ?o) ,
   ToMultiset(
     Distinct(
       Project( ToList(BGP(?o ?p ?z)), {?o} )
     )
   )
)

18.3.4 그룹, 집계, HAVING, 최종 VALUES 절 및 SELECT 표현식 변환

이 단계에서는 질의 수준의 절을 다음 순서로 처리합니다.

  • 그룹화
  • 집계
  • HAVING
  • VALUES
  • Select 표현식
18.3.4.1 그룹화와 집계

단계: GROUP BY

GROUP BY 키워드가 사용되었거나, HAVING 또는 ORDER BY 절에서 집계를 사용했기 때문에, 또는 투영에서 집계를 사용했기 때문에 암시적 그룹화가 있는 경우, 그룹화는 Group 함수에 의해 수행됩니다. 이 경우 그룹화 전에 ToList 함수를 적용하여 해 집합을 해 시퀀스로 변환합니다. 다음으로 Group 함수는 이 해 시퀀스를 하나 이상의 해로 이루어진 그룹들로 나누며, 전체 카디널리티는 동일하게 유지합니다. 암시적 그룹화의 경우, 모든 해를 하나의 그룹으로 묶기 위해 고정 상수(1)가 사용됩니다.

단계: 집계

집계 단계는 질의 수준에 대한 변환으로 적용되며, 질의 수준의 집계 표현식을 Aggregation() 대수 표현식으로 대체합니다.

집계를 사용하는 질의 수준에 대한 변환은 아래와 같습니다.

Issue 247: 그룹화와 집계에 대한 변환 알고리즘의 사소한 문제 spec:editorial
다음 알고리즘에는 몇 가지 사소한 문제가 있습니다.
Let A := the empty sequence
Let Q := the query level being evaluated
Let P := algebraic query expression produced for the GroupGraphPattern of the query level
Let E := [], a list of pairs of the form (variable, expression)

If Q contains GROUP BY exprlist
   Let Grp := Group(exprlist, ToList(P))
Else If Q contains an aggregate in SELECT, HAVING, ORDER BY
   Let Grp := Group((1), ToList(P))
Else
   skip the rest of the Aggregates step
   End

Global i := 1   # Initially 1 for each query processed

For each (X AS Var) in SELECT, each HAVING(X), and each ORDER BY X in Q
  For each unaggregated variable V in X
      Replace V with SAMPLE(V)
      End
  For each aggregate R(args ; scalarvals) now in X
      # note: scalarvals may be omitted; if so, it is equivalent to the empty function
      Ai := Aggregation(args, R, scalarvals, Grp)
      Replace R(...) with aggi in Q
      i := i + 1
      End
  End

For each variable V appearing outside of an aggregate
   Ai := Aggregation(V, Sample, {}, Grp)
   E := E append (V, aggi)
   i := i + 1
   End

A := Ai, ..., Ai-1
P := AggregateJoin(A)

목록 E18.3.4.4 SELECT 표현식 절에서 SELECT 표현식을 변환할 때 사용됩니다.

18.3.4.2 HAVING

HAVING 표현식은 FILTER()와 같은 규칙을 사용하여 평가됩니다. HAVING 절이 평가되는 논리적 위치 때문에, SELECT 절에 의해 투영된 표현식은 HAVING 절에서 보이지 않는다는 점에 유의하십시오.

Let Q := the query level being evaluated
Let P := the algebraic query expression produced for the query level so far

For each HAVING(E) in Q
    P := Filter(E, P)
    End
18.3.4.3 VALUES

질의에 뒤따르는 VALUES 절이 있는 경우:

Let P := the algebraic query expression produced for the query level so far
P := Join(P, ToMultiset(data))
  where data is a solution sequence derived from the VALUES clause

데이터의 변환은 인라인 데이터의 경우와 같습니다.

18.3.4.4 SELECT 표현식

단계: Select 표현식

고려해야 할 추상 구문의 형식은 두 가지입니다.

SELECT selItem ... { pattern }
SELECT * { pattern }
Let X := algebraic query expression from earlier steps
Let VS := set of all variables visible in the pattern,
           so restricted by sub-SELECT projected variables and GROUP BY variables.
           Not visible: only in filter, exists/not exists, masked by a subselect, 
                        non-projected GROUP variables, only in the right hand side of MINUS

Let PV := {}, a set of variable names
Let E := a list of pairs of the form (variable, expression), populated in Section 18.3.4.1 Grouping and Aggregation
  
If "SELECT *"
    PV := VS

If  "SELECT selItem ..."
    For each selItem
        If selItem is a variable
            PV := PV ∪ { variable }
        End
        If selItem is (expr AS var)
            var must not appear in VS nor in PV; if it does then generate a syntax error and stop
            PV := PV ∪ { var }
            E := E append (var, expr) 
        End
    End

For each pair (var, expr) in E
    X := Extend(X, var, expr)
    End
  
Result is X  
The set PV is used later for projection (see Section 18.3.5.2 Projection).

AS의 명명 대상(예: ... AS ?x)으로 변수를 사용할 때, 그 변수가 SELECT의 WHERE 절 안에서 사용되었거나 이 SELECT 표현식에서 이미 AS의 대상으로 사용된 경우 구문 오류가 발생합니다.

18.3.5 해 수정자 변환

해 수정자는 패턴 일치 이후의 SPARQL 질의 처리에 적용됩니다.

해 수정자는 해 매핑의 시퀀스에 대해 작동하므로, 이 시점까지 생성된 질의 결과는 먼저 해 매핑의 다중집합에서 그러한 시퀀스로 변환됩니다. 이 시퀀스에는 암시된 순서가 없고, 중복이 반드시 인접할 필요도 없지만, 포함하는 원소와 그 다중성의 관점에서는 다중집합과 동일합니다. 다중집합에서 시퀀스로의 이 변환을 적용하기 위해, 해 수정자를 대수 질의 표현식으로 변환하는 알고리즘은 다음 단계로 시작합니다. 여기서 A는 이전 절의 알고리즘에 의해 생성된 대수 질의 표현식입니다.

Let M := ToList(A)

이제 해 수정자는 다음 순서로 적용됩니다.

  • Order by
  • Projection
  • Distinct
  • Reduced
  • Offset
  • Limit
18.3.5.1 ORDER BY

질의 문자열에 ORDER BY 절이 있는 경우

M := OrderBy(M, list of order comparators)

18.3.5.2 투영

투영 변수 집합 PVSELECT 표현식 처리에서 계산되었습니다.

M := Project(M, PV)

18.3.5.3 DISTINCT

질의가 DISTINCT를 포함하는 경우,

M := Distinct(M)

18.3.5.4 REDUCED

질의가 REDUCED를 포함하는 경우,

M := Reduced(M)

18.3.5.5 OFFSET과 LIMIT

질의가 "OFFSET offset"과 "LIMIT limit"을 포함하는 경우

M := Slice(M, offset, limit)

질의가 "OFFSET offset"은 포함하지만 "LIMIT limit"은 포함하지 않는 경우

M := Slice(M, offset)

질의가 "LIMIT limit"은 포함하지만 "OFFSET offset"은 포함하지 않는 경우

M := Slice(M, 0, limit)

18.3.5.6 최종 대수 질의 표현식
전체 대수 질의 표현식은 M입니다.

18.4 기본 그래프 패턴

그래프 패턴을 일치시킬 때, 가능한 해는 다중집합을 형성하며, 이는 bag이라고도 합니다. 다중집합은 각 원소가 둘 이상 나타날 수 있는 원소들의 순서 없는 컬렉션입니다. 이는 원소들의 집합과 이러한 각 원소의 다중성(즉, 그 원소가 다중집합에 포함되는 횟수)을 주는 함수로 설명됩니다.

해 매핑은 μ로 씁니다.

dom(μ0)이 빈 집합이 되도록 하는 매핑은 μ0로 씁니다.

정확히 빈 매핑 μ0 하나로 이루어지고 다중성이 1인 다중집합은 Ω0로 씁니다. 이는 join 항등원입니다.

해 매핑 변수 x를 RDF 용어 t로 매핑하는 것은 μ(x)로 씁니다 : { (x, t) }.

정의: 호환 가능한 매핑

두 해 매핑 μ1과 μ2는, dom(μ1)과 dom(μ2) 모두에 있는 모든 변수 v에 대해 μ1(v) = μ2(v)이면 호환 가능합니다.

여기서 μ1(v) = μ2(v)는 μ1(v)와 μ2(v)가 같은 RDF 용어임을 의미합니다.

μ1과 μ2가 호환 가능하면 μ1 ∪ μ2도 매핑입니다. μ1 ∪ μ2를 merge(μ1, μ2)로 씁니다.

정의: 다중성

해 매핑의 다중집합 Ω와 해 매핑 μ가 주어졌을 때, multiplicity(μ | Ω)는 μΩ에 나타나는 횟수를 나타내는 것으로 씁니다.

마찬가지로, 해 시퀀스 Ψ와 해 매핑 μ가 주어졌을 때, multiplicity(μ | Ψ)는 μΨ에 나타나는 횟수를 나타내는 것으로 씁니다.

18.4.1 SPARQL 기본 그래프 패턴 일치

기본 그래프 패턴은 질의의 해당 부분에 대한 활성 그래프와 일치됩니다. 기본 그래프 패턴은 변수와 빈 노드를 모두 용어로 대체하여 인스턴스화할 수 있으며, 이는 두 가지 인스턴스 개념을 제공합니다. 빈 노드는 빈 노드에서 RDF 용어로 가는 RDF 인스턴스 매핑,  σ를 사용하여 대체되고, 변수는 질의 변수에서 RDF 용어로 가는 해 매핑으로 대체됩니다.

정의: 패턴 인스턴스 매핑

패턴 인스턴스 매핑 P는 RDF 인스턴스 매핑 σ와 해 매핑 μ의 조합입니다. P(x) = μ(σ(x))

BGP 'x'에 대해, P(x)는 σ가 정의된 x 안의 빈 노드 b를 σ(b)로, μ가 정의된 x 안의 모든 변수 v를 μ(v)로 대체한 결과를 나타냅니다.

임의의 패턴 인스턴스 매핑은 그것을 각각 질의 변수와 빈 노드로 제한하여 얻어지는 유일한 해 매핑과 유일한 RDF 인스턴스 매핑을 정의합니다.

정의: 기본 그래프 패턴 일치

BGP를 기본 그래프 패턴이라고 하고 G를 RDF 그래프라고 합시다.

P(BGP)가 G의 하위 그래프이고 μ가 BGP 안의 질의 변수로 제한된 P인 패턴 인스턴스 매핑 P가 존재할 때, μ는 G로부터 BGP에 대한 입니다.

multiplicity( μ | Ω ) = P = μ(σ)가 패턴 인스턴스 매핑이고 P(BGP)가 G의 하위 그래프가 되도록 하는 서로 다른 RDF 인스턴스 매핑 σ의 수입니다.

기본 그래프 패턴이 빈 집합이면, 해는 Ω0입니다.

18.4.2 빈 노드의 처리

이 정의는 해 매핑이 기본 그래프 패턴 BGP 안의 변수를 G 안의 빈 노드에 바인딩하는 것을 허용합니다. SPARQL은 결과 형식 문서 (SPARQL Query Results XML Format (Second Edition), SPARQL 1.1 Query Results JSON FormatSPARQL 1.1 Query Results CSV and TSV Formats)의 빈 노드 식별자를 문서에 범위가 지정된 것으로 처리하므로, 이들은 데이터셋의 활성 그래프 안의 노드를 식별하는 것으로 이해될 수 없습니다. DS가 질의의 데이터셋이면, 패턴 해는 따라서 DS 자체의 활성 그래프에서 온 것이 아니라, 범위 지정 그래프라고 불리는 RDF 그래프에서 온 것으로 이해됩니다. 이 그래프는 DS의 활성 그래프이지만, 그 빈 노드들이 RDF 그래프 병합 때와 비슷하게, DS에도 BGP에도 없는 새로운 빈 노드들로 균일하게 대체된 그래프입니다. 같은 범위 지정 그래프가 하나의 질의에 대한 모든 해에 사용됩니다. 범위 지정 그래프는 순전히 이론적인 구성물이며, 실제로는 빈 노드 식별자의 문서 범위 규약만으로 그 효과가 얻어집니다.

RDF 빈 노드는 많은 패턴에 대해 무한히 많은 중복 해를 허용하므로, (빈 노드를 서로 다른 빈 노드로 대체하여 얻어지는) 패턴 해가 무한히 많을 수 있습니다. 따라서 기본 그래프 패턴에 대한 해를 어떻게든 한정할 필요가 있습니다. SPARQL은 기본 그래프 패턴의 해를 결정하기 위해 하위 그래프 일치 기준을 사용합니다. 기본 그래프 패턴에서 활성 그래프의 부분집합으로 가는 서로 다른 패턴 인스턴스 매핑마다 하나의 해가 있습니다.

이는 중복 제거보다 계산의 용이성에 맞춰 최적화되어 있습니다. 따라서 데이터셋의 활성 그래프가 lean인 경우에도 질의 결과가 중복을 포함할 수 있으며, 논리적으로 동등한 데이터셋이 서로 다른 질의 결과를 낼 수 있습니다.

18.5 속성 경로 패턴

이 절은 속성 경로 패턴의 평가를 정의합니다. 속성 경로 패턴은 주어 끝점(RDF 용어 또는 변수), 속성 경로 표현식, 그리고 객체 끝점으로 구성됩니다.

속성 경로 표현식의 변환은 모든 속성 경로 표현식대수 속성 경로 표현식으로 변환합니다. 예를 들어 속성 경로 표현식 (:p/:q)*는 시퀀스 속성 경로를 포함하는 ZeroOrMorePath 표현식이며, 대수 속성 경로 표현식 ZeroOrMorePath( Seq(Link(:p), Link(:q)) )로 변환됩니다.

그 후 속성 경로 패턴의 변환은 이러한 대수 속성 경로 표현식 중 일부를 다른 SPARQL 그래프 패턴으로 변환합니다. 예를 들어 길이가 1인 속성 경로를 트리플 패턴으로 변환하고, 이는 다시 기본 그래프 패턴으로 결합됩니다. 그 결과 연산자 Alt, ZeroOrOnePath, ZeroOrMorePath, OneOrMorePath, 및 NPS를 가진 대수 속성 경로 표현식과, 이러한 연산자 안에 포함된 대수 속성 경로 표현식이 남게 됩니다.

이렇게 남은 대수 속성 경로 표현식을 가진 속성 경로 패턴은 대수 구문 안에서 끝점 XY에 대해 Path(X, ppe, X) 형식으로 나타납니다.

표기법

속성 경로 패턴의 평가를 나타내기 위해, 형식이 Path(X, ppe, Y)인 모든 대수 질의 표현식에 대해 다음과 같이 씁니다.

ppeval(X, ppe, Y)

이는 해 매핑의 다중집합을 생성하며, 각 해 매핑은 사용된 변수에 대한 바인딩을 가집니다(XY 각각은 변수가 될 수 있습니다). 일부 연산자는 해 매핑의 집합만 생성합니다.

표기 x가 다음인 경우
x:term RDF 용어
x:var 변수
Issue 349: 속성 경로 패턴의 평가에서 질의 대상 그래프가 명시적이지 않음
ppeval의 시그니처는 다음과 같이 확장되어야 합니다: ppeval(X, ppe, Y, G), 여기서 G는 RDF 그래프입니다.

모든 평가는 전체 질의 평가의 해당 지점에서 활성 그래프를 일치시키는 방식으로 수행됩니다. 명확성을 위해 각 정의에 활성 그래프를 명시적으로 포함하는 것은 생략합니다.

정의: 술어 속성 경로의 평가

iri를 IRI라고 합시다.

ppeval(X, Link(iri), Y) = evaluation of basic graph pattern {X iri Y}

XY가 모두 변수이면, 이는 다음과 같습니다.

ppeval(X:var, Link(iri), Y:var) =
    { (X, xn:term) (Y, yn:term) | triple (xn, iri, yn) is in the active graph }

X가 변수이고 Y가 RDF 용어이면:

ppeval(X:var, Link(iri), Y:term) =
    { (X, xn:term) | triple (xn, iri, Y) is in the active graph }

X가 RDF 용어이고 Y가 변수이면:

ppeval(X:term, Link(iri), Y:var) =
    { (Y, yn:term) | triple (X, iri, yn) is in the active graph }

XY가 모두 RDF 용어이면:

ppeval(X:term, Link(iri), Y:term)
    = { μ0 } if triple (X, iri, Y) is in the active graph
    = { { } } = Ω0 

ppeval(X:term, Link(iri), Y:term) =
     { } if triple (X, iri, Y) is not in the active graph

비공식적으로, 술어 속성 경로를 평가하는 것은 질의 평가의 해당 지점에서 하위 질의 SELECT * { X iri Y }를 실행하는 것과 같습니다.

정의: 역 속성 경로의 평가

ppe대수 속성 경로 표현식이라고 하면:

ppeval(X, Inv(ppe), Y) = ppeval(Y, ppe, X)

정의: 시퀀스 속성 경로의 평가

ppe1ppe2대수 속성 경로 표현식이라고 합시다. V를 새로운 변수라고 합시다.

ppeval(X, Seq(ppe1, ppe2), Y) = ToMultiSet( Project(ToList(A), PV) )

여기서 A = Join( ppeval(X, ppe1, V), ppeval(V, ppe2, Y) ) 이고 PV = { projVar ∈ {X,Y} | projVar is a variable }입니다.

비공식적으로, 이는 다음과 같습니다.

SELECT * { X P1 _:a . _:a P2 Y }

여기서 P1속성 경로 표현식이며, 이는 변환되어 대수 속성 경로 표현식 ppe1이 될 수 있고, P2ppe2로 변환될 수 있습니다. 이 관찰은 빈 노드 _:a가 (단순 함의 아래에서) 변수처럼 동작하지만 SELECT *의 결과에는 나타나지 않는다는 사실에 기반합니다.

정의: 대안 속성 경로의 평가

ppe1ppe2대수 속성 경로 표현식이라고 합시다.

ppeval(X, Alt(ppe1, ppe2), Y) =
    Union( ppeval(X, ppe1, Y), ppeval(X, ppe2, Y) )

비공식적으로, 이는 다음과 같습니다.

SELECT * { { X P1 Y } UNION { X P2 Y } }

여기서 P1속성 경로 표현식이며, 이는 변환되어 대수 속성 경로 표현식 ppe1이 될 수 있고, P2ppe2로 변환될 수 있습니다.

정의: 그래프의 노드 집합

그래프 G의 노드 집합 nodes(G)는 다음과 같습니다.

nodes(G) = { n | n is an RDF term that is used as a subject or object of an asserted triple of G}

정의: ZeroOrOnePath의 평가

ppe대수 속성 경로 표현식이라고 합시다. G활성 그래프라고 합시다.

ppeval(X:term, ZeroOrOnePath(ppe), Y:var) = 
    { (Y, yn) | yn = X or {(Y, yn)} in ppeval(X, ppe, Y) }
ppeval(X:var, ZeroOrOnePath(ppe), Y:term) =
    { (X, xn) | xn = Y or {(X, xn)} in ppeval(X, ppe, Y) }
ppeval(X:term, ZeroOrOnePath(ppe), Y:term) = 
    { {} } if X = Y or ppeval(X,ppe,X) is not empty
    { } otherwise
ppeval(X:var, ZeroOrOnePath(ppe), Y:var) = 
    { (X, xn) (Y, yn) | 
        either (yn in nodes(G) and xn = yn)
        or {(X, xn), (Y, yn)} in ppeval(X, ppe, Y) }

ZeroOrMorePathOneOrMorePath의 정의에서 사용되는 보조 함수 ALP를 정의합니다. 여기에 제시된 알고리즘은 이 기능을 지정하기 위한 것임에 유의하십시오. 구현자는 전체 질의에 대해 같은 결과를 산출하는 어떤 방법으로든 평가를 구현할 수 있습니다. ZeroOrMorePathOneOrMorePath 형식은 경로로 연결된 서로 다른 노드에 기반한 일치를 반환합니다.

일치 알고리즘은 모든 경로를 따라가고, 그래프 노드 (주어 또는 객체)가 해당 경로에서 이미 방문되었는지를 감지하는 데 기반합니다.

비공식적으로, 이 알고리즘은 각 단계에서 주어진 대수 속성 경로 표현식 ppe를 한 번 적용하여 결과의 다중집합을 확장하려고 하며, 이 특정 경로에 대해 어떤 노드를 방문했는지를 기록합니다. 고려 중인 경로에서 이미 방문된 노드는 다른 단계의 후보가 아닙니다.

정의: 함수 ALP

Let ppe be an algebraic property path expression.
Let reachableTerms(x:term, ppe) be the set of RDF terms
 reached by repeated matches of ppe,
 when starting at RDF term x.

  ALP(x:term, ppe) =
      Let V = empty set of terms
      ALP_recurse(x:term, ppe, V)
      return is V

  ALP_recurse(x:term, ppe, V:set of RDF terms) =
      if ( x in V ) return 
      add x to V
      X = reachableTerms(x, ppe)
      For n:term in X
          ALP_recurse(n, ppe, V)
          End

정의: ZeroOrMorePath의 평가

ppe대수 속성 경로 표현식이라고 합시다. G활성 그래프라고 합시다.

ppeval(X:term, ZeroOrMorePath(ppe), vy:var) =
    { { (vy, n) } | n in ALP(X, ppe) }

ppeval(vx:var, ZeroOrMorePath(ppe), vy:var) =
    { { (vx, t), (vy, n) } |  
      t in nodes(G), (vy, n) in ppeval(t, ZeroOrMorePath(ppe), vy) }

ppeval(vx:var, ZeroOrMorePath(ppe), y:term) = 
    ppeval(y:term, ZeroOrMorePath(Inv(ppe)), vx:var)

ppeval(x:term, ZeroOrMorePath(ppe), y:term) = 
    { { } } if { (vy:var,y) } in ppeval(x, ZeroOrMorePath(ppe), vy)
    { } otherwise

정의: OneOrMorePath의 평가

ppe대수 속성 경로 표현식이라고 합시다. G활성 그래프라고 합시다.

# For OneOrMorePath, we take one step of the path then start
# recording nodes for results.

ppeval(x:term, OneOrMorePath(ppe), vy:var) = { { (vy, t) } | t in V }
    where V is the set of RDF terms that is returned by the
    following algorithm.

    Let X = reachableTerms(x, ppe)
    Let V = the empty multiset
    For n in X
        ALP_recurse(n, ppe, V)
    End
    result is V

ppeval(vx:var, OneOrMorePath(ppe), vy:var) =
     { { (vx, t), (vy, n) } |
         t in nodes(G), (vy, n) in ppeval(t, OneOrMorePath(ppe), vy) }

ppeval(vx:var, OneOrMorePath(ppe), y:term) =
    ppeval(y:term, OneOrMorePath(Inv(ppe)), vx)

ppeval(x:term, OneOrMorePath(ppe), y:term) =
    { { } } if { (vy:var, y) } in ppeval(x, OneOrMorePath(ppe), vy)
    { } otherwise

정의: 부정 속성 집합의 평가

Write μ' as the extension of a solution mapping:
μ'(μ, x) = μ(x)   if x is a variable
μ'(μ, t) = t      if t is an RDF term
Let x and y be variables or RDF terms, S a set of IRIs,
and G the active graph.

   ppeval(x, NPS(S), y) =
       { μ | ∃ triple(μ'(μ, x), p, μ'(μ, y)) in G, such that the IRI of pS }

18.6 SPARQL 대수

SPARQL 추상 질의에 남아 있는 각 기호에 대해, 평가를 위한 연산자를 정의합니다. 같은 이름의 SPARQL 대수 연산자는 "평가 의미론" 절에서 설명한 대로 SPARQL 추상 질의 노드를 평가하는 데 사용됩니다. 기본 그래프 패턴과 속성 경로 패턴의 평가는 앞에서 설명했습니다.

정의: Filter

Ω를 해 매핑의 다중집합, expr표현식, D데이터셋, G활성 그래프라고 합시다. 다음과 같이 정의합니다:

Filter(expr, Ω, D, G) = { μ in Ω | expr(μ, D, G) is an RDF term t such that EBV(t) is "true"^^xsd:boolean }

multiplicity( μ | Filter(expr, Ω, D, G) ) = multiplicity( μ | Ω )

여기서 모든 해 매핑 μ에 대해, expr(μ, D, G)는 활성 그래프 G를 가진 데이터셋 D의 문맥에서, μ에 대해 표현식 expr평가한 결과입니다.

정의: Join

Ω1Ω2를 해 매핑의 다중집합이라고 합시다. 다음과 같이 정의합니다:

Join(Ω1, Ω2) = { merge(μ1, μ2) | μ1 in Ω1 and μ2 in Ω2, and μ1 and μ2 are compatible }

multiplicity( μ | Join(Ω1, Ω2) ) =
    for each merge(μ1, μ2), μ1 in Ω1 and μ2 in Ω2 such that μ = merge(μ1, μ2),
        sum over (μ1, μ2), multiplicity( μ1 | Ω1 ) * multiplicity( μ2 | Ω2 )

Join 안의 해 매핑 μ가 조인되는 다중집합의 서로 다른 해 매핑 μ1μ2에서 생겨날 수 있습니다. μ의 다중성은 모든 가능성에서 온 다중성의 합입니다.

정의: Diff

Ω1Ω2를 해 매핑의 다중집합, expr표현식, D데이터셋, G활성 그래프라고 합시다. 다음과 같이 정의합니다:

Diff(Ω1, Ω2, expr, D, G) = { μ in Ω1 | for every μ' in Ω2, any of the following conditions holds:

  • μμ'호환 가능하지 않음,
  • μμ'호환 가능하고 expr(merge(μ, μ'), D, G)가 오류임, 또는
  • μμ'호환 가능하고 expr(merge(μ, μ'), D, G)가 RDF 용어 t이며, 그 EBV(t)가 "true"^^xsd:boolean이 아님.

}

multiplicity( μ | Diff(Ω1, Ω2, expr, D, G) ) = multiplicity( μ | Ω1 )

여기서 모든 해 매핑 μ에 대해, expr(μ, D, G)는 활성 그래프 G를 가진 데이터셋 D의 문맥에서, μ에 대해 표현식 expr평가한 결과입니다.

DiffLeftJoin의 정의에서 내부적으로 사용됩니다.

정의: LeftJoin

Ω1Ω2를 해 매핑의 다중집합, expr표현식, D데이터셋, G활성 그래프라고 합시다. 다음과 같이 정의합니다:

LeftJoin(Ω1, Ω2, expr, D, G) = Filter(expr, Join(Ω1, Ω2), D, G) ∪ Diff(Ω1, Ω2, expr, D, G)

multiplicity( μ | LeftJoin(Ω1, Ω2, expr, D, G) ) = multiplicity( μ | Filter(expr, Join(Ω1, Ω2), D, G) ) + multiplicity( μ | Diff(Ω1, Ω2, expr, D, G) )

정의: Union

Ω1Ω2를 해 매핑의 다중집합이라고 합시다. 다음과 같이 정의합니다:

Union(Ω1, Ω2) = { μ | μ in Ω1 or μ in Ω2 }

multiplicity( μ | Union(Ω1, Ω2) ) = multiplicity( μ | Ω1 ) + multiplicity( μ | Ω2 )

정의: Minus

Ω1Ω2를 해 매핑의 다중집합이라고 합시다. 다음과 같이 정의합니다:

Minus(Ω1, Ω2) = { μ | μ in Ω1 . ∀ μ' in Ω2, either μ and μ' are not compatible or dom(μ) and dom(μ') are disjoint }

multiplicity( μ | Minus(Ω1, Ω2) ) = multiplicity( μ | Ω1 )

dom(μ)와 dom(μ')에 대한 추가 제한은, 그렇지 않으면 Ω2 안에 Ω1의 해 매핑들과 공통 변수를 갖지 않는 해 매핑이 있을 때, Ω2의 나머지와 무관하게 Minus(Ω1, Ω2)가 비게 되기 때문에 추가됩니다. 빈 해 매핑은 다른 모든 해 매핑과 호환 가능하므로, 그렇지 않으면 임의의 패턴 P에 대해 P MINUS {}가 비게 됩니다.

정의: Extend

μ를 해 매핑, Ω를 해 매핑의 다중집합, var를 변수, expr표현식, D데이터셋, G활성 그래프라고 합시다. 다음과 같이 정의합니다:

Extend(Ω, var, expr, D, G) = { Extend(μ', var, expr, D, G) | μ' in Ω },

multiplicity( μ | Extend(Ω, var, expr, D, G) ) = multiplicity( μ' | Ω ) if there exists a solution mapping μ' in Ω such that μ = Extend(μ', var, expr, D, G),

multiplicity( μ | Extend(Ω, var, expr, D, G) ) = 0 if no such solution mapping μ' exists in Ω,

여기서 모든 해 매핑 μ'에 대해,

Extend(μ', var, expr, D, G) = μ' ∪ { (var, expr(μ', D, G)) } if var not in dom(μ') and expr(μ', D, G) is an RDF term,

Extend(μ', var, expr, D, G) = μ' if var not in dom(μ') and expr(μ', D, G) is an error,

Extend(μ', var, expr, D, G) is undefined if var in dom(μ'), and

expr(μ', D, G) is the result of evaluating expression expr with respect to μ', in the context of dataset D with active graph G.

Cx에 대한 조건일 때, 원소들의 시퀀스는 [ x | C ]로 씁니다.

정의: ToList

Ω를 해 매핑의 다중집합이라고 합시다. 다음과 같이 정의합니다:

ToList(Ω) = 임의의 순서로 된 Ω 안의 매핑 μ들의 시퀀스이며, 각 μmultiplicity( μ | Ω )번 나타납니다.

multiplicity( μ | ToList(Ω) ) = multiplicity( μ | Ω )

정의: OrderBy

Ψ를 해 매핑의 시퀀스라고 합시다. 다음과 같이 정의합니다:

OrderBy(Ψ, condition) = [ μ | μ in Ψ and the sequence satisfies the ordering condition]

multiplicity( μ | OrderBy(Ψ, condition) ) = multiplicity( μ | Ψ )

정의: Project

Ψ를 해 매핑의 시퀀스, PV를 변수 집합이라고 합시다.

매핑 μ에 대해, Proj(μ, PV)는 μPV 안의 변수들로 제한한 것으로 씁니다.

Project(Ψ, PV) = [ Proj(μ, PV) | μ in Ψ ]

multiplicity( μ | Project(Ψ, PV) ) = sum( multiplicity( μ' | Ψ ) | μ' in Ψ such that μ' = Proj(μ, PV) )

Project(Ψ, PV)의 순서는 OrderBy가 부여한 모든 순서를 보존해야 합니다.

정의: Distinct

Ψ를 해 매핑의 시퀀스라고 합시다. 다음과 같이 정의합니다:

Distinct(Ψ) = [ μ | μ in Ψ ]

multiplicity( μ | Distinct(Ψ) ) = 1 for every μDistinct(Ψ)

multiplicity( μ | Distinct(Ψ) ) = 0 for every μDistinct(Ψ)

Distinct(Ψ)의 순서는 OrderBy가 부여한 모든 순서를 보존해야 합니다.

정의: Reduced

Ψ를 해 매핑의 시퀀스라고 합시다. 다음과 같이 정의합니다:

Reduced(Ψ) = [ μ | μ in Ψ ]

multiplicity( μ | Reduced(Ψ) ) is between 1 and multiplicity( μ | Ψ ) for every μReduced(Ψ)

multiplicity( μ | Reduced(Ψ) ) = 0 for every μReduced(Ψ)

Reduced(Ψ)의 순서는 OrderBy가 부여한 모든 순서를 보존해야 합니다.

Reduced 해 시퀀스 수정자는 정의된 다중성을 보장하지 않습니다.

정의: Slice

Ψ를 해 매핑의 시퀀스, offsetlimit를 음이 아닌 정수라고 합시다. 다음과 같이 정의합니다:

Slice(Ψ, offset) = Ψ0   if offsetCard(Ψ)

Slice(Ψ, offset) = subseq(Ψ, offset+1, Card(Ψ))   if 0 ≤ offset < Card(Ψ)

Slice(Ψ, offset, limit) = Ψ0   if offsetCard(Ψ) or limit = 0

Slice(Ψ, offset, limit) = subseq(Ψ, offset+1, Card(Ψ))   if 0 ≤ offset < Card(Ψ) and limitCard(Ψ)−offset

Slice(Ψ, offset, limit) = subseq(Ψ, offset+1, offset+limit)   if 0 ≤ offset < Card(Ψ) and 0 < limit < Card(Ψ)−offset

여기서 Ψ0는 해 매핑의 빈 시퀀스이고, 임의의 두 정수 ij에 대해, subseq(Ψ, i, j)는 Ψi번째 원소로 시작하여 Ψj번째 원소로 끝나는 부분 시퀀스입니다.

이 정의는 시퀀스가 1부터 시작하며 부분 시퀀스가 양 끝을 모두 포함한다고 가정한다는 점에 유의하십시오 (즉, j번째 원소로 끝난다는 것은 해당 부분 시퀀스가 Ψj번째 원소를 마지막 원소로 포함한다는 의미입니다).

정의: ToMultiSet

Ψ를 해 시퀀스라고 합시다. 다음과 같이 정의합니다:

ToMultiSet(Ψ) = { μ | μ in Ψ }

multiplicity( μ | ToMultiSet(Ψ) ) = multiplicity( μ | Ψ )

18.6.1 집계 대수

Group은 해의 어떤 속성을 기준으로 해 시퀀스를 여러 해로 그룹화하는 함수입니다.

정의: Group

Group은 표현식 목록을 해 시퀀스 Ψ에 대해 평가하여, 키에서 해 시퀀스로 가는 부분 함수를 생성합니다.

Group(exprlist, Ψ) = { ListEval(exprlist, μ) → [ μ' | μ' in Ψ such that ListEval(exprlist, μ') and ListEval(exprlist, μ) are the same ] | μ in Ψ },

여기서 ListEval 함수가 생성한 두 목록 LL'은 다음 두 목록의 원소 수가 같고, 두 목록 안의 모든 위치 k에 대해 다음 두 조건 중 하나가 참이면 같은 것으로 간주됩니다:

  • Lk번째 위치의 원소가 RDF 용어이고, L'k번째 위치의 원소도 RDF 용어이며, 이 두 RDF 용어가 같은 용어
  • Lk번째 위치의 원소가 오류이고, L'k번째 위치의 원소도 오류임

정의: ListEval

ListEval((expr1, ..., exprn), μ)는 목록 (e1, ..., en)을 반환하며, 여기서 ei = expri(μ) 또는 오류입니다.

ListEval은 목록 원소의 평가에서 발생한 오류를 유지합니다.

ListEval의 결과가 오류를 포함할 수 있고, 오류가 그룹화에 사용될 수 있더라도, 오류 값을 포함하는 해는 그룹 및 집계 함수의 평가가 끝날 때 제거된다는 점에 유의하십시오.

또한 ListEval((unbound), μ)의 결과는 목록 (error)라는 점에 유의하십시오. 바인딩되지 않은 표현식의 평가는 오류이기 때문입니다.

Aggregation은 집계 표현식의 출력으로 스칼라 값을 계산하는 함수입니다. 이는 SELECT 절, HAVING 평가 과정, 그리고 필요한 경우 ORDER BY에서 사용됩니다. Aggregation은 집합 함수를 사용하여 해 그룹에 대한 집계 값을 계산합니다.

정의: Aggregation

exprlist를 표현식 목록 또는 *, func를 집합 함수, scalarvals를 질의의 집계에서 전달되는 부분 함수(빈 정의역을 가질 수도 있음), 그리고 { key1Ψ1, ..., keymΨm }를 그룹화 단계가 생성한 키에서 해 시퀀스로 가는 부분 함수라고 합시다.

Aggregation은 집합 함수 func를 주어진 집합에 적용하고, 각 키와 그 키에 대한 해 그룹마다 하나의 값을 생성합니다.

Aggregation(exprlist, func, scalarvals, { key1Ψ1, ..., keymΨm } )
   = { (key, F(Ψ)) | keyΨ in { key1Ψ1, ..., keymΨm } }

where
  M(Ψ) = [ ListEval(exprlist, μ) | μ in Ψ ]
  F(Ψ) = func(M(Ψ), scalarvals), for non-DISTINCT
  F(Ψ) = func(Dedup(M(Ψ)), scalarvals), for DISTINCT

여기서 Dedup(M(Ψ))는 시퀀스 M(Ψ)의 순서를 보존하고 중복이 없는 버전입니다. 즉, Dedup(M(Ψ))는 다음 네 가지 속성을 가진 목록들의 시퀀스입니다 (이 시퀀스 안의 각 목록은 ListEval 함수가 생성하므로 RDF 용어와 오류를 포함할 수 있습니다).

  1. M(Ψ) 안의 모든 목록 L에 대해, Dedup(M(Ψ)) 안에 L과 같은 목록 L'이 존재합니다. 여기서 M(Ψ)에서 온 두 목록 LL'이 같은지는 Group 연산자의 정의에서 지정한 대로 판단합니다.
  2. Dedup(M(Ψ)) 안의 모든 목록 L에 대해, M(Ψ) 안에 L과 같은 목록 L'이 존재합니다.
  3. Dedup(M(Ψ))에는 중복이 없습니다. 즉, Dedup(M(Ψ))의 i번째 위치의 목록은, ij인 임의의 두 자연수 ij에 대해, Dedup(M(Ψ))의 j번째 위치의 목록과 같은 목록이 아닙니다.
  4. Dedup(M(Ψ)) 안의 임의의 두 목록 L1L2에 대해, M(Ψ)에서 이들의 첫 출현의 상대적 순서는 Dedup(M(Ψ))에서도 보존됩니다. 즉, i1 < i2이면 j1 < j2입니다. 여기서
    • i1L1이 M(Ψ)의 i1번째 위치에 있는 최소 자연수이고,
    • i2L2가 M(Ψ)의 i2번째 위치에 있는 최소 자연수이며,
    • j1은 Dedup(M(Ψ))에서 L1의 위치이고,
    • j2는 Dedup(M(Ψ))에서 L2의 위치입니다.

특수한 경우: COUNT가 표현식 *와 함께 사용될 때, F(Ψ)는 그룹 해 시퀀스의 카디널리티, 즉 F(Ψ) = Card(Ψ)입니다. DISTINCT 키워드가 있으면 F(Ψ) = Card(Distinct(Ψ))입니다.

scalarvals는 그룹화 메커니즘을 우회하여, 기반 집합 함수에 값을 전달하는 데 사용됩니다. 예를 들어 집계 표현식 GROUP_CONCAT(?x ; separator="|")는 { "separator" → "|" }라는 scalarvals 인자를 가집니다.

모든 집계는 인자 목록의 첫 번째 토큰으로 DISTINCT 키워드를 가질 수 있습니다. 이 키워드가 있으면 func의 첫 번째 인자는 Dedup(M(Ψ))입니다.

예제

다음 값을 가진 해 시퀀스 Ψ가 주어졌다고 합시다:

?x ?y ?z
μ1 1 2 3
μ2 1 3 4
μ3 2 5 6

그리고 질의 표현식 SELECT (ex:agg(?y, ?z) AS ?agg) WHERE { ?x ?y ?z } GROUP BY ?x가 있습니다.

우리는 G = Group((?x), Ψ) = { (1) → [μ1, μ2], (2) → [μ3] }를 생성합니다.

따라서 Aggregation((?y, ?z), ex:agg, {}, G) =
{ ((1), eg:agg([(2, 3), (3, 4)], {})), ((2), eg:agg([(5, 6)], {})) }입니다.

정의: AggregateJoin

S1, ..., Sn을 집합들의 목록이라고 합시다. 각 집합 SiAggregation이 생성한 키에서 (집계된) 값으로 가는 매핑을 포함합니다.

K = { key | key in dom(Sj) for some 1 ≤ jn }를 키들의 집합이라고 하면,
AggregateJoin(S1, ..., Sn) = { agg1val1, ..., aggnvaln | key in K and keyvali in Si for each 1 ≤ in }

18.6.1.1 집합 함수

SPARQL 집계의 기반이 되는 집합 함수들은 모두 공통 시그니처를 가집니다: SetFunc(S) 또는 SetFunc(S, scalarvals)입니다. 여기서 S는 목록들의 시퀀스이고, scalarvals는 SPARQL 문법에서 집계의 ( ... ; key=value ) 구문을 통해 간접적으로 집합 함수에 전달되는 하나 이상의 스칼라 값입니다. SPARQL Query 1.1의 내장 집계에서 지원되는 유일한 사용은 GROUP_CONCAT이며, 예를 들어 GROUP_CONCAT(?x ; separator=", ")입니다.

"집합 함수"라는 이름은 어느 정도 역사적이라는 점에 유의하십시오 — 집합 함수의 인자는 실제로는 시퀀스입니다. 이 이름은 다중집합에 대해 작동하는 SQL 집합 함수와의 공통성 때문에 유지됩니다.

이 문서에서 정의하는 집합 함수는 Count, Sum, Min, Max, Avg, GroupConcat, 그리고 Sample이며, 각각 집계 COUNT, SUM, MIN, MAX, AVG, GROUP_CONCAT, SAMPLE에 대응합니다. 정의는 다음 절들에서 찾을 수 있습니다. 시스템은 함수와 캐스트에 사용하는 것과 같은 표기법으로 로컬 확장을 사용하여 이 집합을 확장할 수 있습니다. 단, ; separator가 사용되지 않는 한, 이는 집계가 사용된 질의에 오류가 있는지 판단하기 전에 어떤 IRI가 함수, 캐스트 또는 집계를 참조하는지 파서가 알아야 함을 의미합니다.

다음 절들의 집합 함수 정의는 두 함수 FlattenCard에 기반하며, 이들은 다음과 같이 정의됩니다.

Flatten은 목록들의 시퀀스를 하나의 목록으로 축약하는 데 사용되는 함수입니다. 예를 들어 [(1, 2), (3, 4)]는 (1, 2, 3, 4)가 됩니다.

정의: Flatten

S를 목록들의 시퀀스, 즉 S = [L1, L2, ..., Lm]라고 합시다. 여기서 모든 i ∈ {1, ..., m}에 대해 Li는 목록입니다.

Flatten(S)는 목록 ( x | L in S and x in L )입니다.

Card는 시퀀스나 원소 목록의 카디널리티를 반환하는 함수입니다(해당 원소는 문맥에 따라 해 매핑 또는 다른 유형의 원소일 수 있습니다).

정의: Card

시퀀스 또는 목록 L이 주어졌을 때, Card(L)는 L의 카디널리티입니다.

18.6.1.2 Count

Count는 주어진 표현식이 집계 그룹 안에서 바인딩되고 오류가 아닌 값을 가지는 횟수를 세는 SPARQL 집합 함수입니다.

정의: Count

xsd:integer Count(sequence S)

Count(S) = Card(L'),

여기서 L'는 목록 L = Flatten(S)에서 모든 오류 원소를 제거한 목록입니다.

18.6.1.3 Sum

Sum은 집계 그룹 안의 값들을 더해 얻은 숫자 값을 반환하는 SPARQL 집합 함수입니다. 타입 승격은 op:numeric-add 함수에 따라 전이적으로 적용되어 일어납니다 (아래 정의 참조). 따라서 ?x가 1(integer), 2.0e0(float), 3.0(decimal) 값을 갖는 집계 그룹에서 SUM(?x)의 값은 6.0(float)이 됩니다.

정의: Sum

numeric Sum(sequence S)

Sum(S) = SumList(L),

여기서 L = Flatten(S)이고 SumList(L)은 다음과 같이 재귀적으로 정의됩니다.

  • Card(L) = 0이면, SumList(L) = "0"^^xsd:integer입니다.
  • Card(L) = 1이면, SumList(L) = op:numeric-add(L1, 0)입니다.
  • Card(L) > 1이면, SumList(L) = op:numeric-add(L1, SumList(L2..n))입니다.

L1L의 첫 번째 원소이고, L2..nL에서 첫 번째 원소를 제외한 것임에 유의하십시오.

이 방식으로, Sum( [(1), (2), (3)] ) = SumList( (1, 2, 3) ) = op:numeric-add(1, op:numeric-add(2, op:numeric-add(3, 0)))입니다.

18.6.1.4 Avg
Avg 집합 함수는 그룹에 대한 표현식의 평균 값을 계산합니다. 이는 Sum과 Count의 관점에서 정의됩니다.

정의: Avg

numeric Avg(sequence S)

Count(S) = 0이면, Avg(S) = "0"^^xsd:integer입니다.

Count(S) > 0이면, Avg(S) = Sum(S) / Count(S)입니다.

예를 들어, Avg([(1), (2), (3)]) = Sum([(1), (2), (3)])/Count([(1), (2), (3)]) = 6/3 = 2입니다.

18.6.1.5 Min

Min은 그룹에서 최솟값을 반환하는 SPARQL 집합 함수입니다.

이는 임의로 타입 지정된 표현식에 대한 정렬을 허용하기 위해 SPARQL ORDER BY 정렬 정의를 사용합니다.

정의: Min

RDFterm Min(sequence S)

Min(S) = MinList(L),

여기서 LFlatten(S)을 통해 얻은 값들의 목록을 ORDER BY ASC 절에 따라 정렬한 것이고, MinList(L)은 다음과 같이 정의됩니다.

  • Card(L) = 0이면, MinList(L) = error입니다.
  • Card(L) > 0이면, MinList(L) = L1입니다. 여기서 L1L의 첫 번째 원소입니다.
18.6.1.6 Max

Max는 그룹에서 최댓값을 반환하는 SPARQL 집합 함수입니다.

이는 임의로 타입 지정된 표현식에 대한 정렬을 허용하기 위해 SPARQL ORDER BY 정렬 정의를 사용합니다.

정의: Max

RDFterm Max(sequence S)

Max(S) = MaxList(L),

여기서 LFlatten(S)을 통해 얻은 값들의 목록을 ORDER BY DESC 절에 따라 정렬한 것이고, MaxList(L)은 다음과 같이 정의됩니다.

  • Card(L) = 0이면, MaxList(L) = error입니다.
  • Card(L) > 0이면, MaxList(L) = L1입니다. 여기서 L1L의 첫 번째 원소입니다.
18.6.1.7 GroupConcat

GroupConcat은 그룹과 함께 표현식의 값들에 걸쳐 문자열 연결을 수행하는 집합 함수입니다. 문자열의 순서는 지정되지 않습니다. 연결에 사용되는 구분 문자는 스칼라 인자 SEPARATOR로 지정할 수 있습니다.

정의: GroupConcat

xsd:string GroupConcat(sequence S, function scalarvals)

GROUP_CONCAT에서 scalarvals 인자가 없으면, scalarvals는 빈 함수로 간주됩니다.

sep를 다음과 같이 정의되는 문자열이라고 합시다.

  • scalarvals가 인자 "separator"에 대해 정의되어 있으면, sep = scalarvals("separator")입니다.
  • scalarvals가 인자 "separator"에 대해 정의되어 있지 않으면, sep는 "space" 문자(즉, 유니코드 코드 포인트 U+0020)입니다.

GroupConcat(S, scalarvals) = GCList(L, sep),

여기서 L = Flatten(S)이고 GCList(L, sep)는 다음과 같이 재귀적으로 정의됩니다.

  • Card(L) = 0이면, GCList(L, sep) = ""입니다.
  • Card(L) = 1이면, GCList(L, sep) = CONCAT("", L1)입니다.
  • Card(L) > 1이면, GCList(L, sep) = CONCAT(L1, sep, GCList(L2..n, sep))입니다.

L1L의 첫 번째 원소이고, L2..nL에서 첫 번째 원소를 제외한 것임에 유의하십시오.

예를 들어, GroupConcat([("a"), ("b"), ("c")], {"separator" → "."}) = GCList( ("a", "b", "c"), "." ) = "a.b.c"입니다.

18.6.1.8 Sample

Sample은 전달된 시퀀스에서 임의의 값을 반환하는 집합 함수입니다.

정의: Sample

RDFterm Sample(sequence S)

Card(S) = 0이면, Sample(S) = error입니다.

Card(S) > 0이면, Sample(S) = v입니다. 여기서 vFlatten(S) 안에 있습니다.

예를 들어 Sample([("a"), ("b"), ("c")])가 주어지면, "a", "b", "c"가 모두 유효한 반환값입니다. Sample 함수는 주어진 입력에 대해 결정적일 필요가 없다는 점에 유의하십시오. 유일한 제한은 출력값이 입력 시퀀스 안에 있어야 한다는 것입니다.

18.6.2 평가 의미론

eval(D(G), AQE, μctx)를, 활성 그래프 G를 가진 데이터셋 D에 대해, 해 매핑 μctx와 상관된 대수 질의 표현식 AQE의 평가로 정의합니다.

활성 그래프는 처음에는 D의 기본 그래프이고, μctx는 처음에는 빈 해 매핑 μ0입니다.

참고

μctxμ0와 다를 수 있는 경우는 17.4.1.4 NOT EXISTS와 EXISTS에 정의된 것처럼, EXISTS { pattern } 또는 NOT EXISTS { pattern } 형식의 표현식을 평가할 때입니다.

다음 정의에서 사용되는 추가 기호는 다음과 같습니다:

Issue 225: 해 매핑의 다중집합과 시퀀스에 대해 eval 함수가 정의되어 있지 않음 spec:bug
이 절의 정의는 AQE가 해 매핑의 시퀀스 또는 다중집합인 경우를 다루지 않습니다.

정의: 기본 그래프 패턴의 평가

eval( D(G), BGP, μctx ) = 해 매핑의 다중집합

기본 그래프 패턴 절을 참조하십시오.

정의: 속성 경로 패턴의 평가

eval( D(G), Path(X, path, Y), μctx ) = 해 매핑의 다중집합

속성 경로 패턴 절을 참조하십시오.

정의: ContextSolution의 평가

eval( D(G), ContextSolution, μctx ) = μctx만 포함하고 다중성이 1인 다중집합

정의: Filter의 평가

eval( D(G), Filter(F, A), μctx ) = Filter( F, eval(D(G), A, μctx), D, G )

정의: Join의 평가

eval( D(G), Join(A1, A2), μctx ) = Join( eval(D(G), A1, μctx), eval(D(G), A2, μctx) )

정의: LeftJoin의 평가

eval( D(G), LeftJoin(A1, A2, F), μctx ) = LeftJoin( eval(D(G), A1, μctx), eval(D(G), A2, μctx), F, D, G )

정의: Minus의 평가

eval( D(G), Minus(A1, A2), μctx ) = Minus( eval(D(G), A1, μctx), eval(D(G), A2, μctx) )

정의: Union의 평가

eval( D(G), Union(A1, A2), μctx ) = Union( eval(D(G), A1, μctx), eval(D(G), A2, μctx) )

정의: Graph의 평가

IRI 또는 변수인 모든 x에 대해, eval( D(G), Graph(x, A), μctx ) 는 다음과 같이 정의됩니다:

  • xD 안의 그래프 이름인 IRI이면,
    eval( D(G), Graph(x, A), μctx ) = eval( D(Gx), A, μctx ),
    여기서 GxD 안에서 이름이 x인 명명된 그래프의 RDF 그래프입니다.
  • xD 안의 그래프 이름이 아닌 IRI이면,
    eval( D(G), Graph(x, A), μctx ) 는 빈 다중집합입니다.
  • x가 변수이면,
    eval( D(G), Graph(x, A), μctx ) = Ω,
    여기서 Ω는 다음 알고리즘이 생성하는 해 매핑의 다중집합입니다:
    Ω := the empty multiset
    for each graph name gn in D (recall that a graph name may be an IRI or a blank node)
        G' := the RDF graph of the named graph with name gn in D
        Ω' := eval( D(G'), A, μctx )
        Ω := Union( Ω, Join(Ω', μ) ), where μ = {xgn}
    the result is Ω
정의: Group의 평가

eval( D(G), Group(exprlist, A), μctx ) = Group( exprlist, eval(D(G), A, μctx) )

정의: Aggregation의 평가

eval( D(G), Aggregation(exprlist, func, scalarvals, Grp), μctx ) = Aggregation( exprlist, func, scalarvals, eval(D(G), Grp, μctx) )

정의: AggregateJoin의 평가

eval( D(G), AggregateJoin(A1, ..., An), μctx ) = AggregateJoin( eval(D(G), A1, μctx), ..., eval(D(G), An, μctx) )

eval(D(G), Ai, μctx)가 오류이면, 그것은 무시된다는 점에 유의하십시오.

정의: Extend의 평가

eval( D(G), Extend(A, var, expr), μctx ) = Extend( eval(D(G), A, μctx), var, expr, D, G )

정의: ToList의 평가

eval( D(G), ToList(A), μctx ) = ToList( eval(D(G), A, μctx) )

정의: Distinct의 평가

eval( D(G), Distinct(A), μctx ) = Distinct( eval(D(G), A, μctx) )

정의: Reduced의 평가

eval( D(G), Reduced(A, μctx ) = Reduced( eval(D(G), A, μctx) )

정의: Project의 평가

eval( D(G), Project(A, vars), μctx ) = Project( eval(D(G), A, μctx), vars )

정의: OrderBy의 평가

eval( D(G), OrderBy(A, condition), μctx ) = OrderBy( eval(D(G), A, μctx), condition )

정의: ToMultiSet의 평가

eval( D(G), ToMultiset(A), μctx ) = ToMultiSet( eval(D(G), A, μctx) )

정의: Slice의 평가

eval( D(G), Slice(A, offset), μctx ) = Slice( eval(D(G), A, μctx), offset )

eval( D(G), Slice(A, offset, limit), μctx ) = Slice( eval(D(G), A, μctx), offset, limit )

18.6.3 SPARQL 기본 그래프 일치 확장

전체 SPARQL 설계는 기본 그래프 패턴에 대한 일치 조건을 다시 작성함으로써, 단순 함의보다 더 정교한 형태의 함의를 가정하는 질의에 사용할 수 있습니다. 모든 형태의 함의에 적용되고 불필요하거나 부적절한 중복을 최적으로 제거하는 하나의 일반 형식으로 그러한 조건을 제시하는 것은 미해결 연구 문제이므로, 이 문서는 그러한 해법이 만족해야 하는 필요조건만을 제시합니다. 이 조건들은 각각의 구체적인 경우에 대해 완전한 정의로 확장되어야 합니다.

기본 그래프 패턴은 RDF 그래프가 RDF 트리플에 대해 갖는 관계와 같은 관계를 트리플 패턴에 대해 가지며, 많은 동일한 용어가 이들에게 적용될 수 있습니다. 특히, 두 기본 그래프 패턴은 트리플 패턴의 용어 사이에 전단사 M이 있어 빈 노드를 빈 노드로, 변수·리터럴·IRI를 자기 자신으로 매핑하며, 트리플 ( s, p, o )가 첫 번째 패턴 안에 있을 때 그리고 그때에만 트리플 ( M(s), M(p), M(o) )가 두 번째 패턴 안에 있으면 동등하다고 말합니다. 이 정의는 동등한 패턴들 사이에서 변수 이름을 보존함으로써 RDF 그래프 동등성에 대한 정의를 기본 그래프 패턴으로 확장합니다.

함의 체계는 다음을 지정합니다.

  1. 해당 체계에서 잘 형성된 것으로 불리는 RDF 그래프들의 부분집합
  2. 잘 형성된 그래프들의 부분집합과 잘 형성된 그래프 사이의 함의 관계.

다양한 함의 체계를 질의하기 위한 자세한 정의는 SPARQL 1.1 Entailment Regimes에서 찾을 수 있습니다.

일부 함의 체계는 일부 RDF 그래프를 불일치로 분류할 수 있습니다. 예를 들어, RDF 그래프:

_:x rdf:type xsd:string .
_:x rdf:type xsd:decimal .

는 D가 XSD 데이터 타입들을 포함할 때 D-불일치입니다. 불일치 그래프에 대한 질의의 효과는 이 명세에서 다루지 않으며, 구체적인 SPARQL 확장에서 지정되어야 합니다.

함의 체계 E는 기본 그래프 패턴 평가에 대한 조건을 제공해야 하며, 임의의 기본 그래프 패턴 BGP, 임의의 RDF 그래프 G, 그리고 해당 조건을 만족하는 임의의 평가에 대해, 결과 해의 다중집합이 RDF 그래프 동등성까지 유일하게 결정되도록 해야 합니다. E를 사용하여 G 위에서 BGP를 평가하여 얻은 해의 다중집합을 Eval-E(G, BGP)로 나타냅니다.
함의 체계는 또한 다음 조건들을 만족해야 합니다:

  1. 임의의 E-일관적인 활성 그래프 AG에 대해, 함의 체계 E는 AG와 E-동등한 범위 지정 그래프 SG를 유일하게 지정합니다.
  2. E에 대해 잘 형성된 그래프들의 집합이 지정되어, 임의의 기본 그래프 패턴 BGP, 범위 지정 그래프 SG, 그리고 Eval-E(SG, BGP) 안의 해 매핑 μ에 대해, 그래프 μ(BGP)가 E에 대해 잘 형성되도록 해야 합니다.
  3. 임의의 기본 그래프 패턴 BGP와 범위 지정 그래프 SG에 대해, μ1, ..., μn이 Eval-E(SG, BGP) 안에 있고 BGP1, ..., BGPn이 모두 BGP와 동등하지만 서로 간에도 SG와도 빈 노드를 공유하지 않는 기본 그래프 패턴이면, 다음이 성립합니다.

    SG E-entails (SG union μ1(BGP1) union ... union μn(BGPn))

    이 조건들은 가능한 답의 집합을 완전히 결정하지 않습니다. RDF는 무제한의 중복을 허용하기 때문입니다. 따라서 추가로 다음이 성립해야 합니다.

  4. 함의 체계는 해당 체계에 적절한 경우, 자명한 무한 해 다중집합을 방지하는 조건을 제공해야 합니다.
18.6.3.1 참고

(a) SG는 종종 AG와 그래프 동등하지만, 이를 E-동등성으로 제한하면 예를 들어 의미론적 중복 제거와 같은 일부 형태의 정규화를 질의 전에 원본 문서에 적용할 수 있습니다.

(b) 조건 3의 구성은 해 매핑이 도입한 모든 빈 노드가 SG 안에서 빈 노드가 나타나는 방식과 내부적으로 일관된 방식으로 사용되도록 보장합니다. 이는 답 집합에서 빈 노드 식별자가 둘 이상의 답에 나타나는 경우, 그렇게 식별된 빈 노드들이 실제로 SG에서 동일할 때에만 그렇게 되도록 보장합니다. 확장이 빈 노드에 대한 바인딩을 허용하지 않으면, 이 조건은 다음 조건으로 단순화될 수 있습니다:

각 해 매핑 μ에 대해 SG E-entails μ(BGP).

(c) 이 조건들은 SG가 AG 또는 BGP와 빈 노드를 공유하지 않는다는 SPARQL 요구 사항을 부과하지 않습니다. 특히, SG가 실제로 AG가 되는 것을 허용합니다. 이는 빈 노드 식별자가 질의와 원본 문서 사이에서, 또는 여러 질의에 걸쳐 그 의미를 유지하는 질의 프로토콜을 허용합니다. 그러나 이러한 프로토콜은 현재 SPARQL 프로토콜 명세에서 지원되지 않습니다.

(d) 조건 1부터 3까지는 답에 대한 필요조건일 뿐이므로, 조건 4는 합법적인 답의 집합이 여러 방식으로 제한될 수 있는 경우를 허용합니다.

(e) 이 조건들 중 어느 것도 BGP 안의 빈 노드에 대한 인스턴스 매핑을 명시적으로 언급하지 않습니다. 일부 함의 체계에서는 빈 노드의 존재적 해석이 단일 인스턴스 매핑의 존재만으로 완전히 포착될 수 없습니다. 이 조건들은 그러한 체계가 질의 패턴 안의 빈 노드에 '완전히 존재적인' 해석을 부여할 수 있게 합니다.

E가 단순 함의인 경우, SG에 대한 SPARQL 조건이 SG가 AG와 그래프 동등하지만 AG 또는 BGP와 빈 노드를 공유하지 않는다는 것(첫 번째 조건을 만족함)이라는 점을 고려하면, SPARQL이 이러한 조건들을 만족함을 보이는 것은 간단합니다. 자명하지 않은 유일한 조건은 (3)입니다.

모든 해 매핑 μi에 대해, 기본 그래프 패턴 일치의 정의에 의해 RDF 인스턴스 매핑 σi가 존재하여 Pi(BGPi)가 SG의 하위 그래프가 됩니다. 여기서 Pi는 μi와 σi로 구성된 패턴 인스턴스 매핑입니다. BGPi와 SG는 공통 빈 노드를 갖지 않으므로, σi와 μi의 치역에는 BGPi의 빈 노드가 포함되지 않습니다. 따라서 해 매핑 μi와 Pi의 RDF 인스턴스 매핑 σi는 서로 교환 가능하므로, Pi(BGPi) = σii(BGPi))입니다. 따라서

P1(BGP1) union ... union Pn(BGPn)
= σ11(BGP1)) union ... union σnn(BGPn))
= [ σ1 + ... + σn]( μ1(BGP1) union ... union μn(BGPn) )

σi RDF 인스턴스 매핑들의 정의역이 모두 서로 배타적이기 때문입니다. 이들은 또한 SG와도 배타적이므로,

SG union [ σ1 + ... + σn]( μ1(BGP1) union ... union μn(BGPn) )
= [ σ1 + ... + σn](SG union μ1(BGP1) union ... union μn(BGPn) )

즉,

SG union μ1(BGP1) union ... union μn(BGPn)

는 SG의 하위 그래프인 인스턴스를 가지므로, RDF 보간 보조정리 [RDF12-SEMANTICS]에 의해 SG가 단순 함의합니다.

19. SPARQL 문법

SPARQL 문법은 SPARQL Query와 SPARQL 1.1 Update를 모두 다룹니다.

19.1 SPARQL 문자열

SPARQL 문자열은 이 절에 제시된 문법을 따르는 RDF 문자열입니다.

참고

RDF 문자열유니코드 스칼라 값유니코드 코드 포인트들의 시퀀스입니다. 유니코드 스칼라 값은 서러게이트 코드 포인트를 포함하지 않습니다.

SPARQL 질의 문자열SPARQL 문자열이며, QueryUnit 생성식에서 시작하는 문법을 따릅니다.

SPARQL update 문자열SPARQL 문자열이며, UpdateUnit 생성식에서 시작하는 문법을 따릅니다.

향후 버전의 유니코드와의 호환성을 위해, 이 문자열의 문자는 이 출판일 현재 할당되지 않은 유니코드 코드 포인트를 포함할 수 있습니다 (Unicode Identifiers and Syntax [UAX31] 4절 Pattern Syntax 참조). 제외된 문자 클래스를 가진 생성식 (예: [^<>'{}|^`])의 경우, 문자는 #x0 - #x10FFFF 범위에서 제외됩니다.

19.2 이스케이프 시퀀스

SPARQL 문서에는 세 가지 형태의 이스케이프가 사용됩니다:

이스케이프 시퀀스는 다음 위치에서 사용할 수 있습니다:

숫자
이스케이프
문자열
이스케이프
예약 문자
이스케이프
IRI, RDF 용어로 사용되거나, PREFIX 또는 BASE 선언에서 사용됨 아니요 아니요
로컬 이름 아니요 아니요
문자열 아니요

이스케이프 시퀀스는 관련 문법 생성식과 일치하는 유니코드 코드 포인트의 시퀀스를 가져온 뒤, 다음 단계를 적용하여 처리됩니다.

  1. 유니코드 코드 포인트의 시퀀스를 왼쪽에서 오른쪽으로 스캔하여 처음 일치하는 이스케이프 시퀀스를 찾습니다.
  2. 이스케이프 시퀀스가 발견되면, 그 이스케이프 시퀀스에 해당하는 코드 포인트(들)가 이스케이프 시퀀스를 대체합니다.
  3. 유니코드 코드 포인트 시퀀스의 스캔은 대체된 이스케이프 시퀀스 바로 다음 코드 포인트부터 계속됩니다.
처리된 이스케이프 시퀀스의 예
입력 코드 포인트 출력 코드 포인트 코드 포인트 수
abc\u005Cdef abc\def 7
abc\u005Ctuv abc\tuv 7
\u005CA \A 2
\\u005C \u005C 6
\u005C\u005C \\ 2
\\\u005C \\ 2
\\\\ \\ 2
\u005Cn \n 2
참고

%-인코딩된 시퀀스는 IRI의 문자 범위 안에 있으며 로컬 이름에서 명시적으로 허용됩니다. 이들은 % 다음에 두 개의 16진수 문자가 오는 형태로 나타나며, 동일한 세 문자 시퀀스를 나타냅니다. 이러한 시퀀스는 처리 중에 디코딩되지 않습니다. Turtle에서 <http://a.example/%66oo-bar>로 작성된 용어는 IRI http://a.example/%66oo-bar를 지정하며, IRI http://a.example/foo-bar를 지정하지 않습니다. 접두사 PREFIX ex: <http://a.example/>와 함께 ex:%66oo-bar로 작성된 용어도 IRI http://a.example/%66oo-bar를 지정합니다.

19.3 공백

공백(생성식 WS)은 그렇지 않으면 하나의 터미널로 (잘못) 인식될 두 터미널을 분리하는 데 사용됩니다. 아래에서 대문자로 된 규칙 이름은 공백이 의미 있는 위치를 나타냅니다. 이들은 SPARQL 파서를 구성하기 위한 터미널의 가능한 선택지를 형성합니다. 공백은 문자열 안에서 의미가 있습니다. 그 밖의 경우, 토큰 사이의 공백은 무시됩니다.

예:

?a<?b&&?c>?d

이는 변수 '?a', IRI '<?b&&?c>', 변수 '?d'로 이루어진 토큰 시퀀스이며, '<'(보다 작음) 및 '>'(보다 큼)를 사용한 두 표현식을 연산자 '&&'가 연결하는 표현식이 아닙니다.

19.4 주석

SPARQL 질의의 주석은 IRI 또는 문자열 바깥의 '#' 형식을 취하며, 줄 끝(0x0D 또는 0x0A 문자로 표시됨)까지, 또는 주석 표시 뒤에 줄 끝이 없으면 파일 끝까지 계속됩니다. 주석은 공백으로 처리됩니다.

19.5 IRI 참조

IRIREF 생성식 및 PrefixedName 생성식(접두사 확장 후)과 일치한 텍스트는, 이스케이프 처리 후, RFC 3987 "ABNF for IRI References and IRIs" [RFC3987] 2.2절의 IRI 참조에 대한 일반 구문을 따라야 합니다. 예를 들어, IRIREF <abc#def>는 SPARQL 질의 문자열 안에 나타날 수 있지만, IRIREF <abc##def>는 나타나서는 안 됩니다.

BASE 키워드로 선언된 기본 IRI는 절대 IRI여야 합니다. PREFIX 키워드로 선언된 접두사는 같은 질의 안에서 다시 선언될 수 없습니다. BASEPREFIX에 대한 설명은 4.1.1절 IRI 용어의 구문을 참조하십시오.

19.6 빈 노드와 빈 노드 식별자

빈 노드는 다음에서 사용할 수 없습니다:

이는 SPARQL update 요청 안에서의 경우입니다.

빈 노드 식별자는 그것이 나타나는 SPARQL 문자열에 범위가 지정됩니다. 요청 문자열 안에서 같은 빈 노드 식별자를 서로 다르게 사용하면 같은 빈 노드를 참조합니다. 각 요청마다 새로운 빈 노드가 생성되며, 요청 사이에서 식별자로 빈 노드를 참조할 수 없습니다.

같은 빈 노드 식별자는 다음에서 사용할 수 없습니다:

같은 빈 노드 식별자는 SPARQL 1.1 Update 요청의 서로 다른 QuadPattern 절에 나타날 수 있음에 유의하십시오.

19.7 문법

문법에서 사용되는 EBNF 표기법은 Extensible Markup Language (XML) 1.1 [XML11] 6절 Notation에 정의되어 있습니다.

문법에는 두 개의 진입점이 있습니다:

  1. SPARQL 질의 언어를 위한 QueryUnit
  2. SPARQL update 언어를 위한 UpdateUnit.

대문자 이름의 규칙을 터미널로 사용할 때 SPARQL 문법은 LL(1)입니다.

참고:

  1. 키워드는 Turtle에 맞춰 rdf:type의 IRI (전체로는 http://www.w3.org/1999/02/22-rdf-syntax-ns#type) 대신 사용되는 키워드 'a'를 제외하고는, 대소문자를 구분하지 않는 방식으로 일치됩니다.
  2. 이스케이프 시퀀스는 대소문자를 구분합니다.
  3. 입력을 토큰화하고 문법 규칙을 선택할 때 가장 긴 일치가 선택됩니다.
  4. 부호 있는 숫자에서는 부호와 숫자 사이에 공백이 허용되지 않습니다. AdditiveExpression 문법 규칙은 표현식 뒤에 부호 있는 숫자가 오는 두 경우를 포괄함으로써 이를 허용합니다. 이들은 적절하게 부호 없는 숫자의 덧셈 또는 뺄셈을 생성합니다.
  5. 토큰 INSERT DATA, DELETE DATADELETE WHERE는 단어 사이에 임의의 양의 공백을 허용합니다. 명확성을 위해 문법에서는 단일 공백 버전이 사용됩니다.
  6. QuadDataQuadPattern 규칙은 모두 Quads 규칙을 사용합니다. INSERT DATADELETE DATA에서 사용되는 QuadData 규칙은 쿼드 패턴 안에 변수를 허용해서는 안 됩니다.
  7. 빈 노드 구문은 DELETE WHERE, DELETEDeleteClause, 그리고 DELETE DATA에서 허용되지 않습니다.
  8. 빈 노드 식별자의 사용을 제한하는 규칙은 19.6 빈 노드와 빈 노드 식별자에 제시되어 있습니다.
  9. VALUES 절의 변수 목록에 있는 변수의 수는 DataBlock 안의 관련 값 목록 각각에 있는 RDF 용어의 수와 일치해야 합니다.
  10. VALUES 절의 변수 목록 안의 변수들은 그 목록 안에서 고유해야 합니다.
  11. SELECT 절에서 AS로 도입되는 변수는 이미 범위 안에 있어서는 안 됩니다.
  12. BIND 절에서 할당되는 변수는 GroupGraphPattern 안의 바로 앞선 TriplesBlock 안에서 이미 사용 중이어서는 안 됩니다.
  13. 집계 함수는 집계를 위한 내장 키워드 중 하나이거나, 구문적으로 함수 호출인 사용자 정의 집계일 수 있습니다. 집계 함수는 SELECT, HAVINGORDER BY 절에서만 사용할 수 있습니다.
  14. 집계 함수의 표현식 인자는 집계 함수를 포함할 수 없습니다.
  15. 사용자 정의 집계 함수만 함수 호출에서 DISTINCT 키워드를 사용할 수 있습니다.
  16. 구체화자 또는 애노테이션 구문은 속성 위치가 단순 경로(IRI, 키워드 a, 또는 변수)일 때만 트리플 뒤에 허용되며, 다른 경로 표현식에는 허용되지 않습니다.
  17. SELECT 절에서 *를 사용하는 것은 GROUP BY 절을 포함하는 질의 안에서, 또는 집계HAVING 또는 ORDER BY 절에 나타나는 경우에는 허용되지 않습니다.
[1]   QueryUnit   ::=   Query
[2]   Query   ::=   Prologue
( SelectQuery | ConstructQuery | DescribeQuery | AskQuery )
ValuesClause
[3]   UpdateUnit   ::=   Update
[4]   Prologue   ::=   ( BaseDecl | PrefixDecl | VersionDecl )*
[5]   BaseDecl   ::=   'BASE' IRIREF
[6]   PrefixDecl   ::=   'PREFIX' PNAME_NS IRIREF
[7]   VersionDecl   ::=   'VERSION' VersionSpecifier
[8]   VersionSpecifier   ::=   STRING_LITERAL1 | STRING_LITERAL2
[9]   SelectQuery   ::=   SelectClause DatasetClause* WhereClause SolutionModifier
[10]   SubSelect   ::=   SelectClause WhereClause SolutionModifier ValuesClause
[11]   SelectClause   ::=   'SELECT' ( 'DISTINCT' | 'REDUCED' )? ( ( Var | ( '(' Expression 'AS' Var ')' ) )+ | '*' )
[12]   ConstructQuery   ::=   'CONSTRUCT' ( ConstructTemplate DatasetClause* WhereClause SolutionModifier | DatasetClause* 'WHERE' ConstructTemplate SolutionModifier )
[13]   DescribeQuery   ::=   'DESCRIBE' ( VarOrIri+ | '*' ) DatasetClause* WhereClause? SolutionModifier
[14]   AskQuery   ::=   'ASK' DatasetClause* WhereClause SolutionModifier
[15]   DatasetClause   ::=   'FROM' ( DefaultGraphClause | NamedGraphClause )
[16]   DefaultGraphClause   ::=   SourceSelector
[17]   NamedGraphClause   ::=   'NAMED' SourceSelector
[18]   SourceSelector   ::=   iri
[19]   WhereClause   ::=   'WHERE'? GroupGraphPattern
[20]   SolutionModifier   ::=   GroupClause? HavingClause? OrderClause? LimitOffsetClauses?
[21]   GroupClause   ::=   'GROUP' 'BY' GroupCondition+
[22]   GroupCondition   ::=   BuiltInCall | FunctionCall | '(' Expression ( 'AS' Var )? ')' | Var
[23]   HavingClause   ::=   'HAVING' HavingCondition+
[24]   HavingCondition   ::=   Constraint
[25]   OrderClause   ::=   'ORDER' 'BY' OrderCondition+
[26]   OrderCondition   ::=   ( ( 'ASC' | 'DESC' ) BrackettedExpression )
| ( Constraint | Var )
[27]   LimitOffsetClauses   ::=   LimitClause OffsetClause? | OffsetClause LimitClause?
[28]   LimitClause   ::=   'LIMIT' INTEGER
[29]   OffsetClause   ::=   'OFFSET' INTEGER
[30]   ValuesClause   ::=   ( 'VALUES' DataBlock )?
[31]   Update   ::=   Prologue ( Update1 ( ';' Update )? )?
[32]   Update1   ::=   Load | Clear | Drop | Add | Move | Copy | Create | DeleteWhere | Modify | InsertData | DeleteData
[33]   Load   ::=   'LOAD' 'SILENT'? iri ( 'INTO' GraphRef )?
[34]   Clear   ::=   'CLEAR' 'SILENT'? GraphRefAll
[35]   Drop   ::=   'DROP' 'SILENT'? GraphRefAll
[36]   Create   ::=   'CREATE' 'SILENT'? GraphRef
[37]   Add   ::=   'ADD' 'SILENT'? GraphOrDefault 'TO' GraphOrDefault
[38]   Move   ::=   'MOVE' 'SILENT'? GraphOrDefault 'TO' GraphOrDefault
[39]   Copy   ::=   'COPY' 'SILENT'? GraphOrDefault 'TO' GraphOrDefault
[40]   InsertData   ::=   'INSERT DATA' QuadData
[41]   DeleteData   ::=   'DELETE DATA' QuadData
[42]   DeleteWhere   ::=   'DELETE WHERE' QuadPattern
[43]   Modify   ::=   ( 'WITH' iri )? ( DeleteClause InsertClause? | InsertClause ) UsingClause* 'WHERE' GroupGraphPattern
[44]   DeleteClause   ::=   'DELETE' QuadPattern
[45]   InsertClause   ::=   'INSERT' QuadPattern
[46]   UsingClause   ::=   'USING' ( iri | 'NAMED' iri )
[47]   GraphOrDefault   ::=   'DEFAULT' | 'GRAPH'? iri
[48]   GraphRef   ::=   'GRAPH' iri
[49]   GraphRefAll   ::=   GraphRef | 'DEFAULT' | 'NAMED' | 'ALL'
[50]   QuadPattern   ::=   '{' Quads '}'
[51]   QuadData   ::=   '{' Quads '}'
[52]   Quads   ::=   TriplesTemplate? ( QuadsNotTriples '.'? TriplesTemplate? )*
[53]   QuadsNotTriples   ::=   'GRAPH' VarOrIri '{' TriplesTemplate? '}'
[54]   TriplesTemplate   ::=   TriplesSameSubject ( '.' TriplesTemplate? )?
[55]   GroupGraphPattern   ::=   '{' ( SubSelect | GroupGraphPatternSub ) '}'
[56]   GroupGraphPatternSub   ::=   TriplesBlock? ( GraphPatternNotTriples '.'? TriplesBlock? )*
[57]   TriplesBlock   ::=   TriplesSameSubjectPath ( '.' TriplesBlock? )?
[58]   ReifiedTripleBlock   ::=   ReifiedTriple PropertyList
[59]   ReifiedTripleBlockPath   ::=   ReifiedTriple PropertyListPath
[60]   GraphPatternNotTriples   ::=   GroupOrUnionGraphPattern | OptionalGraphPattern | MinusGraphPattern | GraphGraphPattern | ServiceGraphPattern | Filter | Bind | InlineData
[61]   OptionalGraphPattern   ::=   'OPTIONAL' GroupGraphPattern
[62]   GraphGraphPattern   ::=   'GRAPH' VarOrIri GroupGraphPattern
[63]   ServiceGraphPattern   ::=   'SERVICE' 'SILENT'? VarOrIri GroupGraphPattern
[64]   Bind   ::=   'BIND' '(' Expression 'AS' Var ')'
[65]   InlineData   ::=   'VALUES' DataBlock
[66]   DataBlock   ::=   InlineDataOneVar | InlineDataFull
[67]   InlineDataOneVar   ::=   Var '{' DataBlockValue* '}'
[68]   InlineDataFull   ::=   ( NIL | '(' Var* ')' ) '{' ( '(' DataBlockValue* ')' | NIL )* '}'
[69]   DataBlockValue   ::=   iri | RDFLiteral | NumericLiteral | BooleanLiteral | 'UNDEF' | TripleTermData
[70]   Reifier   ::=   '~' VarOrReifierId?
[71]   VarOrReifierId   ::=   Var | iri | BlankNode
[72]   MinusGraphPattern   ::=   'MINUS' GroupGraphPattern
[73]   GroupOrUnionGraphPattern   ::=   GroupGraphPattern ( 'UNION' GroupGraphPattern )*
[74]   Filter   ::=   'FILTER' Constraint
[75]   Constraint   ::=   BrackettedExpression | BuiltInCall | FunctionCall
[76]   FunctionCall   ::=   iri ArgList
[77]   ArgList   ::=   NIL | '(' 'DISTINCT'? Expression ( ',' Expression )* ')'
[78]   ExpressionList   ::=   NIL | '(' Expression ( ',' Expression )* ')'
[79]   ConstructTemplate   ::=   '{' ConstructTriples? '}'
[80]   ConstructTriples   ::=   TriplesSameSubject ( '.' ConstructTriples? )?
[81]   TriplesSameSubject   ::=   VarOrTerm PropertyListNotEmpty | TriplesNode PropertyList | ReifiedTripleBlock
[82]   PropertyList   ::=   PropertyListNotEmpty?
[83]   PropertyListNotEmpty   ::=   Verb ObjectList ( ';' ( Verb ObjectList )? )*
[84]   Verb   ::=   VarOrIri | 'a'
[85]   ObjectList   ::=   Object ( ',' Object )*
[86]   Object   ::=   GraphNode Annotation
[87]   TriplesSameSubjectPath   ::=   VarOrTerm PropertyListPathNotEmpty | TriplesNodePath PropertyListPath | ReifiedTripleBlockPath
[88]   PropertyListPath   ::=   PropertyListPathNotEmpty?
[89]   PropertyListPathNotEmpty   ::=   ( VerbPath | VerbSimple ) ObjectListPath ( ';' ( ( VerbPath | VerbSimple ) ObjectListPath )? )*
[90]   VerbPath   ::=   Path
[91]   VerbSimple   ::=   Var
[92]   ObjectListPath   ::=   ObjectPath ( ',' ObjectPath )*
[93]   ObjectPath   ::=   GraphNodePath AnnotationPath
[94]   Path   ::=   PathAlternative
[95]   PathAlternative   ::=   PathSequence ( '|' PathSequence )*
[96]   PathSequence   ::=   PathEltOrInverse ( '/' PathEltOrInverse )*
[97]   PathElt   ::=   PathPrimary PathMod?
[98]   PathEltOrInverse   ::=   PathElt | '^' PathElt
[99]   PathMod   ::=   '?' | '*' | '+'
[100]   PathPrimary   ::=   iri | 'a' | '!' PathNegatedPropertySet | '(' Path ')'
[101]   PathNegatedPropertySet   ::=   PathOneInPropertySet | '(' ( PathOneInPropertySet ( '|' PathOneInPropertySet )* )? ')'
[102]   PathOneInPropertySet   ::=   iri | 'a' | '^' ( iri | 'a' )
[103]   TriplesNode   ::=   Collection | BlankNodePropertyList
[104]   BlankNodePropertyList   ::=   '[' PropertyListNotEmpty ']'
[105]   TriplesNodePath   ::=   CollectionPath | BlankNodePropertyListPath
[106]   BlankNodePropertyListPath   ::=   '[' PropertyListPathNotEmpty ']'
[107]   Collection   ::=   '(' GraphNode+ ')'
[108]   CollectionPath   ::=   '(' GraphNodePath+ ')'
[109]   AnnotationPath   ::=   ( Reifier | AnnotationBlockPath )*
[110]   AnnotationBlockPath   ::=   '{|' PropertyListPathNotEmpty '|}'
[111]   Annotation   ::=   ( Reifier | AnnotationBlock )*
[112]   AnnotationBlock   ::=   '{|' PropertyListNotEmpty '|}'
[113]   GraphNode   ::=   VarOrTerm | TriplesNode | ReifiedTriple
[114]   GraphNodePath   ::=   VarOrTerm | TriplesNodePath | ReifiedTriple
[115]   VarOrTerm   ::=   Var | iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | NIL | TripleTerm
[116]   ReifiedTriple   ::=   '<<' ReifiedTripleSubject Verb ReifiedTripleObject Reifier? '>>'
[117]   ReifiedTripleSubject   ::=   Var | iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | ReifiedTriple | TripleTerm
[118]   ReifiedTripleObject   ::=   Var | iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | ReifiedTriple | TripleTerm
[119]   TripleTerm   ::=   '<<(' TripleTermSubject Verb TripleTermObject ')>>'
[120]   TripleTermSubject   ::=   Var | iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | TripleTerm
[121]   TripleTermObject   ::=   Var | iri | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | TripleTerm
[122]   TripleTermData   ::=   '<<(' TripleTermDataSubject ( iri | 'a' ) TripleTermDataObject ')>>'
[123]   TripleTermDataSubject   ::=   iri
[124]   TripleTermDataObject   ::=   iri | RDFLiteral | NumericLiteral | BooleanLiteral | TripleTermData
[125]   VarOrIri   ::=   Var | iri
[126]   Var   ::=   VAR1 | VAR2
[127]   Expression   ::=   ConditionalOrExpression
[128]   ConditionalOrExpression   ::=   ConditionalAndExpression ( '||' ConditionalAndExpression )*
[129]   ConditionalAndExpression   ::=   ValueLogical ( '&&' ValueLogical )*
[130]   ValueLogical   ::=   RelationalExpression
[131]   RelationalExpression   ::=   NumericExpression ( '=' NumericExpression | '!=' NumericExpression | '<' NumericExpression | '>' NumericExpression | '<=' NumericExpression | '>=' NumericExpression | 'IN' ExpressionList | 'NOT' 'IN' ExpressionList )?
[132]   NumericExpression   ::=   AdditiveExpression
[133]   AdditiveExpression   ::=   MultiplicativeExpression ( '+' MultiplicativeExpression | '-' MultiplicativeExpression | ( NumericLiteralPositive | NumericLiteralNegative ) ( ( '*' UnaryExpression ) | ( '/' UnaryExpression ) )* )*
[134]   MultiplicativeExpression   ::=   UnaryExpression ( '*' UnaryExpression | '/' UnaryExpression )*
[135]   UnaryExpression   ::=     '!' UnaryExpression
| '+' PrimaryExpression
| '-' PrimaryExpression
| PrimaryExpression
[136]   PrimaryExpression   ::=   BrackettedExpression | BuiltInCall | iriOrFunction | RDFLiteral | NumericLiteral | BooleanLiteral | Var | ExprTripleTerm
[137]   ExprTripleTerm   ::=   '<<(' ExprTripleTermSubject Verb ExprTripleTermObject ')>>'
[138]   ExprTripleTermSubject   ::=   iri | Var
[139]   ExprTripleTermObject   ::=   iri | RDFLiteral | NumericLiteral | BooleanLiteral | Var | ExprTripleTerm
[140]   BrackettedExpression   ::=   '(' Expression ')'
[141]   BuiltInCall   ::=     Aggregate
| 'STR' '(' Expression ')'
| 'LANG' '(' Expression ')'
| 'LANGMATCHES' '(' Expression ',' Expression ')'
| 'LANGDIR' '(' Expression ')'
| 'DATATYPE' '(' Expression ')'
| 'BOUND' '(' Var ')'
| 'IRI' '(' Expression ')'
| 'URI' '(' Expression ')'
| 'BNODE' ( '(' Expression ')' | NIL )
| 'RAND' NIL
| 'ABS' '(' Expression ')'
| 'CEIL' '(' Expression ')'
| 'FLOOR' '(' Expression ')'
| 'ROUND' '(' Expression ')'
| 'CONCAT' ExpressionList
| SubstringExpression
| 'STRLEN' '(' Expression ')'
| StrReplaceExpression
| 'UCASE' '(' Expression ')'
| 'LCASE' '(' Expression ')'
| 'ENCODE_FOR_URI' '(' Expression ')'
| 'CONTAINS' '(' Expression ',' Expression ')'
| 'STRSTARTS' '(' Expression ',' Expression ')'
| 'STRENDS' '(' Expression ',' Expression ')'
| 'STRBEFORE' '(' Expression ',' Expression ')'
| 'STRAFTER' '(' Expression ',' Expression ')'
| 'YEAR' '(' Expression ')'
| 'MONTH' '(' Expression ')'
| 'DAY' '(' Expression ')'
| 'HOURS' '(' Expression ')'
| 'MINUTES' '(' Expression ')'
| 'SECONDS' '(' Expression ')'
| 'TIMEZONE' '(' Expression ')'
| 'TZ' '(' Expression ')'
| 'NOW' NIL
| 'UUID' NIL
| 'STRUUID' NIL
| 'MD5' '(' Expression ')'
| 'SHA1' '(' Expression ')'
| 'SHA256' '(' Expression ')'
| 'SHA384' '(' Expression ')'
| 'SHA512' '(' Expression ')'
| 'COALESCE' ExpressionList
| 'IF' '(' Expression ',' Expression ',' Expression ')'
| 'STRLANG' '(' Expression ',' Expression ')'
| 'STRLANGDIR' '(' Expression ',' Expression ',' Expression ')'
| 'STRDT' '(' Expression ',' Expression ')'
| 'sameTerm' '(' Expression ',' Expression ')'
| 'isIRI' '(' Expression ')'
| 'isURI' '(' Expression ')'
| 'isBLANK' '(' Expression ')'
| 'isLITERAL' '(' Expression ')'
| 'isNUMERIC' '(' Expression ')'
| 'hasLANG' '(' Expression ')'
| 'hasLANGDIR' '(' Expression ')'
| RegexExpression
| ExistsFunc
| NotExistsFunc
| 'isTRIPLE' '(' Expression ')'
| 'TRIPLE' '(' Expression ',' Expression ',' Expression ')'
| 'SUBJECT' '(' Expression ')'
| 'PREDICATE' '(' Expression ')'
| 'OBJECT' '(' Expression ')'
[142]   RegexExpression   ::=   'REGEX' '(' Expression ',' Expression ( ',' Expression )? ')'
[143]   SubstringExpression   ::=   'SUBSTR' '(' Expression ',' Expression ( ',' Expression )? ')'
[144]   StrReplaceExpression   ::=   'REPLACE' '(' Expression ',' Expression ',' Expression ( ',' Expression )? ')'
[145]   ExistsFunc   ::=   'EXISTS' GroupGraphPattern
[146]   NotExistsFunc   ::=   'NOT' 'EXISTS' GroupGraphPattern
[147]   Aggregate   ::=     'COUNT' '(' 'DISTINCT'? ( '*' | Expression ) ')'
| 'SUM' '(' 'DISTINCT'? Expression ')'
| 'MIN' '(' 'DISTINCT'? Expression ')'
| 'MAX' '(' 'DISTINCT'? Expression ')'
| 'AVG' '(' 'DISTINCT'? Expression ')'
| 'SAMPLE' '(' 'DISTINCT'? Expression ')'
| 'GROUP_CONCAT' '(' 'DISTINCT'? Expression ( ';' 'SEPARATOR' '=' String )? ')'
[148]   iriOrFunction   ::=   iri ArgList?
[149]   RDFLiteral   ::=   String ( LANG_DIR | '^^' iri )?
[150]   NumericLiteral   ::=   NumericLiteralUnsigned | NumericLiteralPositive | NumericLiteralNegative
[151]   NumericLiteralUnsigned   ::=   INTEGER | DECIMAL | DOUBLE
[152]   NumericLiteralPositive   ::=   INTEGER_POSITIVE | DECIMAL_POSITIVE | DOUBLE_POSITIVE
[153]   NumericLiteralNegative   ::=   INTEGER_NEGATIVE | DECIMAL_NEGATIVE | DOUBLE_NEGATIVE
[154]   BooleanLiteral   ::=   'true' | 'false'
[155]   String   ::=   STRING_LITERAL1 | STRING_LITERAL2 | STRING_LITERAL_LONG1 | STRING_LITERAL_LONG2
[156]   iri   ::=   IRIREF | PrefixedName
[157]   PrefixedName   ::=   PNAME_LN | PNAME_NS
[158]   BlankNode   ::=   BLANK_NODE_LABEL | ANON

터미널에 대한 생성식:

[159]   IRIREF   ::=   '<' ( [^<>"{}|^`\]-[#x00-#x20] | UCHAR ) * '>'
[160]   PNAME_NS   ::=   PN_PREFIX? ':'
[161]   PNAME_LN   ::=   PNAME_NS PN_LOCAL
[162]   BLANK_NODE_LABEL   ::=   '_:' ( PN_CHARS_U | [0-9] ) ((PN_CHARS|'.')* PN_CHARS)?
[163]   VAR1   ::=   '?' VARNAME
[164]   VAR2   ::=   '$' VARNAME
[165]   LANG_DIR   ::=   '@' [a-zA-Z]+ ('-' [a-zA-Z0-9]+)* ('--' [a-zA-Z]+)?
[166]   INTEGER   ::=   [0-9]+
[167]   DECIMAL   ::=   [0-9]* '.' [0-9]+
[168]   DOUBLE   ::=   ( ([0-9]+ ('.'[0-9]*)? ) | ( '.' ([0-9])+ ) ) EXPONENT
[169]   EXPONENT   ::=   [eE] [+-]? [0-9]+
[170]   INTEGER_POSITIVE   ::=   '+' INTEGER
[171]   DECIMAL_POSITIVE   ::=   '+' DECIMAL
[172]   DOUBLE_POSITIVE   ::=   '+' DOUBLE
[173]   INTEGER_NEGATIVE   ::=   '-' INTEGER
[174]   DECIMAL_NEGATIVE   ::=   '-' DECIMAL
[175]   DOUBLE_NEGATIVE   ::=   '-' DOUBLE
[176]   STRING_LITERAL1   ::=   "'" ( ([^#x27#x5C#xA#xD]) | ECHAR | UCHAR )* "'"
[177]   STRING_LITERAL2   ::=   '"' ( ([^#x22#x5C#xA#xD]) | ECHAR | UCHAR )* '"'
[178]   STRING_LITERAL_LONG1   ::=   "'''" ( ( "'" | "''" )? ( [^'\] | ECHAR | UCHAR ) )* "'''"
[179]   STRING_LITERAL_LONG2   ::=   '"""' ( ( '"' | '""' )? ( [^"\] | ECHAR | UCHAR ) )* '"""'
[180]   ECHAR   ::=   '\' [tbnrf\"']
[181]   UCHAR   ::=   ('\u' HEX HEX HEX HEX) | ('\U' HEX HEX HEX HEX HEX HEX HEX HEX)
[182]   NIL   ::=   '(' WS* ')'
[183]   WS   ::=   #x20 | #x9 | #xD | #xA
[184]   ANON   ::=   '[' WS* ']'
[185]   PN_CHARS_BASE   ::=   [A-Z] | [a-z] | [#x00C0-#x00D6] | [#x00D8-#x00F6] | [#x00F8-#x02FF] | [#x0370-#x037D] | [#x037F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
[186]   PN_CHARS_U   ::=   PN_CHARS_BASE | '_'
[187]   VARNAME   ::=   ( PN_CHARS_U | [0-9] ) ( PN_CHARS_U | [0-9] | #x00B7 | [#x0300-#x036F] | [#x203F-#x2040] )*
[188]   PN_CHARS   ::=   PN_CHARS_U | '-' | [0-9] | #x00B7 | [#x0300-#x036F] | [#x203F-#x2040]
[189]   PN_PREFIX   ::=   PN_CHARS_BASE ((PN_CHARS|'.')* PN_CHARS)?
[190]   PN_LOCAL   ::=   (PN_CHARS_U | ':' | [0-9] | PLX ) ((PN_CHARS | '.' | ':' | PLX)* (PN_CHARS | ':' | PLX) )?
[191]   PLX   ::=   PERCENT | PN_LOCAL_ESC
[192]   PERCENT   ::=   '%' HEX HEX
[193]   HEX   ::=   [0-9] | [A-F] | [a-f]
[194]   PN_LOCAL_ESC   ::=   '\' ( '_' | '~' | '.' | '-' | '!' | '$' | '&' | "'" | '(' | ')' | '*' | '+' | ',' | ';' | '=' | '/' | '?' | '#' | '@' | '%' )

이 문법의 텍스트 버전은 여기에서 이용할 수 있습니다.

20. 적합성

비규범으로 표시된 절뿐만 아니라, 이 명세의 모든 작성 지침, 다이어그램, 예제 및 참고는 비규범입니다. 이 명세의 그 밖의 모든 내용은 규범입니다.

이 문서에서 핵심어 MAY, MUST, MUST NOT, OPTIONAL, 및 SHOULD는 여기 보이는 것처럼 모두 대문자로 나타날 때에만, BCP 14 [RFC2119] [RFC8174]에 설명된 대로 해석해야 합니다.

20.1 적합성

SPARQL 질의 문자열의 적합성에 대해서는 19 SPARQL 문법 절을 참조하고, 질의 결과의 적합성에 대해서는 16 질의 형식 절을 참조하십시오. application/sparql-query 미디어 타입에 대한 적합성은 22. 인터넷 미디어 타입 절을 참조하십시오.

이 명세는 SPARQL 1.1 Protocol [SPARQL11-PROTOCOL], SPARQL Query Results XML Format (Second Edition) [RDF-SPARQL-XMLRES], SPARQL 1.1 Query Results JSON Format [SPARQL11-RESULTS-JSON] 및 SPARQL 1.1 Query Results CSV and TSV Formats [SPARQL11-RESULTS-CSV-TSV]와 함께 사용되도록 의도되었습니다. 해당 명세들의 적합성 기준은 그 명세들을 참조하십시오.

SPARQL 프로토콜은 SPARQL 질의를 SPARQL 질의 처리 서비스에 전달하고, 질의 결과를 이를 요청한 엔터티에 반환하는 수단을 설명한다는 점에 유의하십시오.

21. 인터넷 미디어 타입 및 파일 확장자

SPARQL Query Language의 인터넷 미디어 타입(이전에는 MIME Type으로 알려짐)은 "application/sparql-query"입니다.

sparql 질의 파일은 모든 플랫폼에서 확장자 ".rq"(소문자)를 가지는 것이 권장됩니다.

타입 이름:
application
하위 타입 이름:
sparql-query
필수 매개변수:
없음
선택적 매개변수:
없음
인코딩 고려사항:
SPARQL Query Language의 구문은 유니코드의 코드 포인트 [UNICODE] 위에서 표현됩니다. 인코딩은 항상 UTF-8 [RFC3629]입니다.
유니코드 코드 포인트는 \uXXXX (U+0부터 U+FFFF) 또는 \UXXXXXXXX 구문(U+0부터 U+10FFFF)으로도 표현할 수 있으며, 여기서 X는 16진수 숫자 [0-9A-Fa-f]이고, 서러게이트 코드 포인트인 U+D800부터 U+DFFF까지는 제외합니다.
보안 고려사항:
SPARQL Query 부록 C, 보안 고려사항UTF-8, a transformation format of ISO 10646 [RFC3629] 7절 Security Considerations를 참조하십시오.
상호운용성 고려사항:
알려진 상호운용성 문제는 없습니다.
게시된 명세:
이 명세.
이 미디어 타입을 사용하는 애플리케이션:
현재 이 미디어 타입을 사용하는 것으로 알려진 애플리케이션은 없습니다.
추가 정보:
매직 넘버:
SPARQL 질의는 문서 시작 부분 근처에 문자열 'PREFIX'(대소문자 독립)를 가질 수 있습니다.
파일 확장자:
".rq"
기본 URI:
SPARQL 'BASE <IRIref>' 용어는 문서 안에서 나중에 순차적으로 사용되는 질의 언어의 상대 IRIref에 대한 현재 기본 URI를 변경할 수 있습니다.
추가 정보를 위한 연락 담당자 및 이메일 주소:
public-rdf-dawg-comments@w3.org
의도된 사용:
COMMON
사용 제한:
없음
작성자/변경 관리 주체:
SPARQL 1.2 명세는 World Wide Web Consortium의 RDF-star Working Group의 작업 산출물입니다. W3C는 이 명세들에 대한 변경 제어권을 가집니다.

A. SPARQL 1.1 Query Language와 SPARQL 1.2 Query Language 사이의 변경 사항

이 절은 비규범입니다.

B. 프라이버시 고려사항

TODO

C. 보안 고려사항

FROM, FROM NAMED 또는 GRAPH를 사용하는 SPARQL 질의는 지정된 URI가 역참조되도록 할 수 있습니다. 이는 네트워크, 디스크 또는 CPU 리소스의 추가 사용과 함께 서비스 거부와 같은 관련 2차 문제를 일으킬 수 있습니다. Uniform Resource Identifier (URI): Generic Syntax [RFC3986] 7절의 보안 문제를 고려해야 합니다. 또한 file: URI의 내용은 어떤 경우에는 접근, 처리 및 결과로 반환될 수 있어, 의도하지 않은 로컬 리소스 접근을 제공할 수 있습니다.

SPARQL 요청은 FROM NAMED와 같이 SPARQL 엔드포인트에서 추가 요청이 발행되도록 할 수 있습니다. 엔드포인트는 조직의 방화벽 또는 DMZ 안에 있을 가능성이 있으므로, 이러한 질의는 간접 공격의 원천이 될 수 있습니다.

SPARQL 언어는 확장을 허용하며, 이러한 확장은 각자의 보안 영향을 가질 것입니다.

여러 IRI가 같은 모양을 가질 수 있습니다. 서로 다른 문자 체계의 문자가 비슷하게 보일 수 있습니다(키릴 문자 "о"가 라틴 문자 "o"와 비슷하게 보일 수 있음). 결합 문자가 뒤따르는 문자는 다른 문자와 동일한 시각적 표현을 가질 수 있습니다(LATIN SMALL LETTER E 뒤에 COMBINING ACUTE ACCENT가 오는 경우 LATIN SMALL LETTER E WITH ACUTE와 동일한 시각적 표현을 가짐). SPARQL 사용자는 데이터 안의 IRI와 일치하는 IRI로 질의를 작성하도록 주의해야 합니다. 유사 문자의 일치에 대한 추가 정보는 Unicode Security Considerations [UTR36] 및 Internationalized Resource Identifiers (IRIs) [RFC3987] 8절에서 찾을 수 있습니다.

D. 국제화 고려사항

TODO

E. 색인

E.1 이 명세에서 정의하는 용어

E.2 참조로 정의되는 용어

F. 참조

F.1 규범적 참조

[BCP47]
언어 식별용 태그. A. Phillips, 편집자; M. Davis, 편집자. IETF. 2009년 9월. 현행 모범 사례. URL: https://www.rfc-editor.org/rfc/rfc5646
[CBD]
CBD - 간결한 경계 설명. Patrick Stickler, Nokia. W3C. 2005년 6월 3일. W3C 회원 제출. URL: https://www.w3.org/Submission/CBD/
[CURIE]
CURIE 구문 1.0. Mark Birbeck; Shane McCarron. W3C. 2010년 12월 16일. W3C 작업 그룹 노트. URL: https://www.w3.org/TR/curie/
[I18N-GLOSSARY]
국제화 용어집. Richard Ishida; Addison Phillips. W3C. 2024년 10월 17일. W3C 작업 그룹 노트. URL: https://www.w3.org/TR/i18n-glossary/
[rdf-concepts]
Resource Description Framework (RDF): 개념 및 추상 구문. Graham Klyne; Jeremy Carroll. W3C. 2004년 2월 10일. W3C 권고안. URL: https://www.w3.org/TR/rdf-concepts/
[RDF-DAWG-UC]
RDF 데이터 접근 사용 사례 및 요구사항. Kendall Clark. W3C. 2005년 3월 25일. W3C 작업 초안. URL: https://www.w3.org/TR/rdf-dawg-uc/
[RDF-SPARQL-XMLRES]
SPARQL 질의 결과 XML 형식(제2 판). Dave Beckett; Jeen Broekstra. W3C. 2013년 3월 21일. W3C 권고안. URL: https://www.w3.org/TR/rdf-sparql-XMLres/
[RDF12-CONCEPTS]
RDF 1.2 개념 및 추상 데이터 모델. Andy Seaborne; Gregg Kellogg; Olaf Hartig; Pierre-Antoine Champin. W3C. 2026년 4월 7일. W3C 후보 권고안. URL: https://www.w3.org/TR/rdf12-concepts/
[RDF12-SEMANTICS]
RDF 1.2 의미론. Peter Patel-Schneider; Enrico Franconi; Dörthe Arndt. W3C. 2026년 4월 7일. W3C 후보 권고안. URL: https://www.w3.org/TR/rdf12-semantics/
[RDF12-XML]
RDF 1.2 XML 구문. Gregg Kellogg; Jerven Bolleman. W3C. 2026년 6월 18일. W3C 작업 초안. URL: https://www.w3.org/TR/rdf12-xml/
[RFC2119]
RFC에서 요구사항 수준을 나타내는 데 쓰는 핵심 단어. S. Bradner. IETF. 1997년 3월. 현행 모범 사례. URL: https://www.rfc-editor.org/rfc/rfc2119
[RFC3629]
UTF-8, ISO 10646의 변환 형식. F. Yergeau. IETF. 2003년 11월. 인터넷 표준. URL: https://www.rfc-editor.org/rfc/rfc3629
[RFC3986]
Uniform Resource Identifier (URI): 일반 구문. T. Berners-Lee; R. Fielding; L. Masinter. IETF. 2005년 1월. 인터넷 표준. URL: https://www.rfc-editor.org/rfc/rfc3986
[RFC3987]
Internationalized Resource Identifiers (IRI). M. Duerst; M. Suignard. IETF. 2005년 1월. 제안 표준. URL: https://www.rfc-editor.org/rfc/rfc3987
[RFC4122]
Universally Unique IDentifier (UUID) URN 네임스페이스. P. Leach; M. Mealling; R. Salz. IETF. 2005년 7월. 제안 표준. URL: https://www.rfc-editor.org/rfc/rfc4122
[RFC4647]
언어 태그의 매칭. A. Phillips, 편집자; M. Davis, 편집자. IETF. 2006년 9월. 현행 모범 사례. URL: https://www.rfc-editor.org/rfc/rfc4647
[RFC8174]
RFC 2119 핵심 단어에서 대문자와 소문자의 모호성. B. Leiba. IETF. 2017년 5월. 현행 모범 사례. URL: https://www.rfc-editor.org/rfc/rfc8174
[SPARQL-FEATURES]
SPARQL 새 기능 및 근거. Kjetil Kjernsmo; Alexandre Passant. W3C. 2009년 7월 2일. W3C 작업 초안. URL: https://www.w3.org/TR/sparql-features/
[SPARQL11-ENTAILMENT]
SPARQL 1.1 함의 체제. Birte Glimm; Chimezie Ogbuji. W3C. 2013년 3월 21일. W3C 권고안. URL: https://www.w3.org/TR/sparql11-entailment/
[SPARQL11-FEDERATED-QUERY]
SPARQL 1.1 페더레이션 질의. Eric Prud'hommeaux; Carlos Buil Aranda. W3C. 2013년 3월 21일. W3C 권고안. URL: https://www.w3.org/TR/sparql11-federated-query/
[SPARQL11-PROTOCOL]
SPARQL 1.1 프로토콜. Lee Feigenbaum; Gregory Williams; Kendall Clark; Elias Torres. W3C. 2013년 3월 21일. W3C 권고안. URL: https://www.w3.org/TR/sparql11-protocol/
[SPARQL11-Query]
SPARQL 1.1 질의 언어. Steven Harris; Andy Seaborne. W3C. 2013년 3월 21일. W3C 권고안. URL: https://www.w3.org/TR/sparql11-query/
[SPARQL11-RESULTS-CSV-TSV]
SPARQL 1.1 질의 결과 CSV 및 TSV 형식. Andy Seaborne. W3C. 2013년 3월 21일. W3C 권고안. URL: https://www.w3.org/TR/sparql11-results-csv-tsv/
[SPARQL11-RESULTS-JSON]
SPARQL 1.1 질의 결과 JSON 형식. Andy Seaborne. W3C. 2013년 3월 21일. W3C 권고안. URL: https://www.w3.org/TR/sparql11-results-json/
[SPARQL11-UPDATE]
SPARQL 1.1 업데이트. Paula Gearon; Alexandre Passant; Axel Polleres. W3C. 2013년 3월 21일. W3C 권고안. URL: https://www.w3.org/TR/sparql11-update/
[SPARQL12-PROTOCOL]
SPARQL 1.2 프로토콜. Andy Seaborne; Ruben Taelman; Gregory Williams; Thomas Pellissier Tanon. W3C. 2026년 4월 26일. W3C 작업 초안. URL: https://www.w3.org/TR/sparql12-protocol/
[SPARQL12-Query]
SPARQL 1.2 질의 언어. Olaf Hartig; Andy Seaborne; Ruben Taelman; Gregory Williams; Thomas Pellissier Tanon. W3C. 2026년 6월 24일. W3C 작업 초안. URL: https://www.w3.org/TR/sparql12-query/
[SPARQL12-Update]
SPARQL 1.2 업데이트. Ruben Taelman; Andy Seaborne; Thomas Pellissier Tanon. W3C. 2026년 6월 12일. W3C 작업 초안. URL: https://www.w3.org/TR/sparql12-update/
[TURTLE]
RDF 1.1 Turtle. Eric Prud'hommeaux; Gavin Carothers. W3C. 2014년 2월 25일. W3C 권고안. URL: https://www.w3.org/TR/turtle/
[UAX31]
Unicode 식별자 및 구문. Mark Davis; Robin Leroy. Unicode Consortium. 2025년 8월 20일. Unicode 표준 부속서 #31. URL: https://www.unicode.org/reports/tr31/tr31-43.html
[UNICODE]
Unicode 표준. Unicode Consortium. URL: https://www.unicode.org/versions/latest/
[UTR36]
Unicode 보안 고려사항. Mark Davis; Michel Suignard. Unicode Consortium. 2014년 9월 19일. Unicode 기술 보고서 #36. URL: https://www.unicode.org/reports/tr36/tr36-15.html
[vcard-rdf]
사람 및 조직을 기술하기 위한 vCard 온톨로지. Renato Iannella; James McKinney. W3C. 2014년 5월 22일. W3C 작업 그룹 노트. URL: https://www.w3.org/TR/vcard-rdf/
[WEBARCH]
월드 와이드 웹의 아키텍처, 제1 권. Ian Jacobs; Norman Walsh. W3C. 2004년 12월 15일. W3C 권고안. URL: https://www.w3.org/TR/webarch/
[XML-NAMES11]
XML 1.1의 네임스페이스(제2 판). Tim Bray; Dave Hollander; Andrew Layman; Richard Tobin 외. W3C. 2006년 8월 16일. W3C 권고안. URL: https://www.w3.org/TR/xml-names11/
[XML11]
Extensible Markup Language (XML) 1.1(제2 판). Tim Bray; Jean Paoli; Michael Sperberg-McQueen; Eve Maler; François Yergeau; John Cowan 외. W3C. 2006년 8월 16일. W3C 권고안. URL: https://www.w3.org/TR/xml11/
[XMLSCHEMA11-2]
W3C XML Schema Definition Language (XSD) 1.1 제2부: 데이터형. David Peterson; Sandy Gao; Ashok Malhotra; Michael Sperberg-McQueen; Henry Thompson; Paul V. Biron 외. W3C. 2012년 4월 5일. W3C 권고안. URL: https://www.w3.org/TR/xmlschema11-2/
[XPATH-31]
XML Path Language (XPath) 3.1. Jonathan Robie; Michael Dyck; Josh Spiegel. W3C. 2017년 3월 21일. W3C 권고안. URL: https://www.w3.org/TR/xpath-31/
[XPATH-DATAMODEL-31]
XQuery 및 XPath 데이터 모델 3.1. Norman Walsh; John Snelson; Andrew Coleman. W3C. 2017년 3월 21일. W3C 권고안. URL: https://www.w3.org/TR/xpath-datamodel-31/
[XPATH-FUNCTIONS-31]
XPath 및 XQuery 함수와 연산자 3.1. Michael Kay. W3C. 2017년 3월 21일. W3C 권고안. URL: https://www.w3.org/TR/xpath-functions-31/

F.2 정보 제공 참조

[RDF12-TURTLE]
RDF 1.2 Turtle. Gregg Kellogg; Andy Seaborne; Dominik Tomaszuk. W3C. 12 June 2026. W3C Working Draft. URL: https://www.w3.org/TR/rdf12-turtle/
[SPARQL12-CONCEPTS]
SPARQL 1.2 Concepts. The W3C RDF & SPARQL Working Group. W3C. W3C Editor's Draft. URL: https://w3c.github.io/sparql-concepts/spec/
[SPARQL12-ENTAILMENT]
SPARQL 1.2 Entailment Regimes. Peter Patel-Schneider. W3C. 9 April 2026. W3C Working Draft. URL: https://www.w3.org/TR/sparql12-entailment/
[SPARQL12-FEDERATED-QUERY]
SPARQL 1.2 Federated Query. Ruben Taelman; Gregory Williams. W3C. 23 April 2026. W3C Working Draft. URL: https://www.w3.org/TR/sparql12-federated-query/
[SPARQL12-GRAPH-STORE-PROTOCOL]
SPARQL 1.2 Graph Store Protocol. Andy Seaborne; Thomas Pellissier Tanon. W3C. 19 December 2024. W3C Working Draft. URL: https://www.w3.org/TR/sparql12-graph-store-protocol/
[SPARQL12-NEW]
What’s New in SPARQL 1.2. The W3C RDF & SPARQL Working Group. W3C. W3C Editor's Draft. URL: https://w3c.github.io/sparql-new/spec/
[SPARQL12-RESULTS-CSV-TSV]
SPARQL 1.2 Query Results CSV and TSV Formats. Ruben Taelman; Gregory Williams; Thomas Pellissier Tanon. W3C. 28 March 2026. W3C Working Draft. URL: https://www.w3.org/TR/sparql12-results-csv-tsv/
[SPARQL12-RESULTS-JSON]
SPARQL 1.2 Query Results JSON Format. Andy Seaborne; Ruben Taelman; Gregory Williams; Thomas Pellissier Tanon. W3C. 28 March 2026. W3C Working Draft. URL: https://www.w3.org/TR/sparql12-results-json/
[SPARQL12-RESULTS-XML]
SPARQL 1.2 Query Results XML Format. Ruben Taelman; Dominik Tomaszuk; Thomas Pellissier Tanon. W3C. 27 December 2024. W3C Working Draft. URL: https://www.w3.org/TR/sparql12-results-xml/
[SPARQL12-SERVICE-DESCRIPTION]
SPARQL 1.2 Service Description. Ruben Taelman; Gregory Williams. W3C. 23 April 2026. W3C Working Draft. URL: https://www.w3.org/TR/sparql12-service-description/