Here are some examples of database query languages that have at least one working implementation, for comparison:
See ExperimentalQueryLanguageComparison for examples in potential future languages.
Example 1: Retrieve all columns/attributes and rows/tuples from a table/RelVar
SQL:
SELECT * FROM myThingsDataphor:
select myThings;Tutorial D:
myThingsDatalog:
?- myThings(A,B,C,Name) // browse the results myThings(A,B,C,Name) // if used in another queryExample 2: Restriction
SQL:
SELECT * FROM myThings WHERE name = 'blah'Dataphor:
select myThings WHERE name = 'blah'Tutorial D:
myThings WHERE name = 'blah'Datalog:
?- myThings(A,B,C,blah)Example 3: Restriction and projection with unique result
SQL:
SELECT DISTINCT a, b, c FROM myThings WHERE name = 'blah' DISTINCT is needed unless a, b, c constitute a key of myThings.Dataphor:
select myThings over {a, b, c} WHERE name = 'blah'Tutorial D:
(myThings WHERE name = 'blah') {a, b, c}Datalog:
query(A,B,C) :- myThings(A,B,C,blah) ?- query(A,B,C)Example 3b: Restriction and projection without required uniqueness
SQL:
SELECT a, b, c FROM myThings WHERE name = 'blah'Example 4: Aggregation
SQL:
SELECT snumber, COUNT(*) AS p_count FROM sp GROUP BY snumberDataphor:
select sp group by {snumber} add { Count() p_count };Tutorial D:
SUMMARIZE sp BY {snumber} ADD (COUNT() AS p_count)Datalog:
support for mutual recursion precludes internal support for aggregation; aggregate would need to be in higher language layer w/ scoped queriesExample 5: Insertion
SQL:
INSERT INTO myThings(a, b, c, name) VALUES (1, 2, 3, 'glub'), (4, 5, 6, 'glob');Dataphor:
insert table { row {a 1, b 2, c 3, name 'glub'}, row {4, 5, 6,'glob'}, } into myThingsTutorial D:
INSERT myThings RELATION { TUPLE {a 1, b 2, c 3, name 'glub'}, TUPLE {a 4, b 5, c 6, name 'glob'} }Datalog:
myThings(1,2,3,glub). myThings(4,5,6,glob).Example 6: Table/relvar creation
SQL:
CREATE TABLE myThings ( name TEXT NOT NULL PRIMARY KEY, a INTEGER, b INTEGER, c INTEGER )Dataphor:
create table Employee { name : String, a: Integer, b: Integer, c: Integer, key { name} };Tutorial D:
VAR myThings REAL RELATION { name CHAR, a INTEGER, b INTEGER, c INTEGER } KEY {name}Datalog:
add first entry to 'myThings' when ready Cannot specify keys.Example 7: Transitive closure or recursion - "all paths" of a digraph
Datalog:
path(A,B) :- edge(A,B). path(A,B) :- edge(A,C),path(C,B). ?- path(A,B).Tutorial D:
TCLOSE edges // presumes degree 2 and matching typesExample 8: Natural equi-join
SQL:
SELECT foo, bar FROM red NATURAL JOIN blueTutorial D:
(red JOIN blue) {foo, bar}Datalog:
no 'natural' joinExample 9: Equi-join
SQL:
SELECT foo, bar FROM red, blue WHERE x = y -- -- Variation 2 -- -- SELECT foo, bar FROM red INNER JOIN blue ON x = yTutorial D:
JOIN {red RENAME (x AS j), blue RENAME (y AS j)} {foo, bar}Datalog:
query(Foo,Bar) :- red(X,Foo),blue(X,Bar) ?- query(A,B)Example 10: Equi-join with same-named key
SQL
SELECT foo, bar FROM red INNER JOIN blue ON red.x = blue.xTutorial D:
(red JOIN blue) {foo, bar}Datalog:
attributes positional in standard DatalogExample 11: Top 3 largest planets, use name if tie
SQL (Microsoft Dialect)
SELECT TOP 3 * FROM planets ORDER BY diameter DESCENDING, nameTutorial D:
WITH (result := planets ORDER(DESC diameter, DESC name)) : WRITELN result[0] || result[1] || result[2];.
Added some DataLog comparisons above. At the moment, Datalog can operate as a query language excepting some functional transforms and a variety of aggregation operations (group by, count, min, max, top N, etc.). Datalog would need some tooling to serve as a data definition or manipulation language (mutations aren't supported, nor is defining tables with keys or enforcing constraints between relations).
In Datalog, aggregations and functions on infinite domains must be lifted into a higher layer - they compete with transitive closures and recursive queries in a manner such that having both features in the same layer leads readily to 'infinite' results sets. I favor lifting them into a 'functional' layer with scoped queries that simply return all the constructed relations. I might eventually explain all this on another page...
These examples would be informative, and more amenable to proof-reading, if they operated on a defined schema.
Good point. As time permits, I'll endeavour to change the above to use either Oracle's familiar DEPT & EMP or ChrisDate's classic SupplierPartsDatabase, etc., and lead off with the table/relvar definitions followed by the 'insert' examples. I'll change the SQL, Dataphor, Tutorial D, and possibly SMEQL (it seems intuitive) examples, but I'll leave the Datalog -- with which I have least familiarity -- examples to their original author.
Chapter 15 (http://web.cecs.pdx.edu/~maier/TheoryBook/MAIER/C15.pdf) of TheTheoryOfRelationalDatabases compares the way to write queries in many (now obsolete?) (pseudo?) relational query languages: ISBL, QUEL, QBE and PIQUE
See: TutorialDee, DataLog, AlphoraDataphor, StructuredQueryLanguage, TqlRoadmap (aka SMEQL), ExperimentalQueryLanguageDiscussion, HowOtherQueryLanguagesAddressSqlFlaws
CategoryQueryLanguage, CategoryProgrammingLanguageComparisons