home shape

SQL / AQL - Comparison

The ArangoDB Query Language (AQL) is similar to the Structured Query Language (SQL) in its purpose. Both support reading and modifying collection data, however AQL does not support data definition operations, such as creating and dropping databases, collections and indexes.

Though some of the keywords overlap, AQL syntax differs from SQL. For instance, the SQL WHERE and AQL FILTER clauses are equivalent in that they both define conditions for returning results. But, SQL uses predefined sequence to determine where the WHERE clause must occur in the statement. In AQL, clauses execute from left to right, so the position of a FILTER clause in the query determines its precedence.

Despite such differences, anyone with an SQL background should have no difficulty in learning AQL. If you run into any problems, we have a table below showing SQL functions and commands with their AQL equivalents.

large right background img

SQL / AQL - Comparison

The ArangoDB Query Language (AQL) is similar to the Structured Query Language (SQL) in its purpose. Both support reading and modifying collection data, however AQL does not support data definition operations, such as creating and dropping databases, collections and indexes.

Though some of the keywords overlap, AQL syntax differs from SQL. For instance, the SQL WHERE and AQL FILTER clauses are equivalent in that they both define conditions for returning results. But, SQL uses predefined sequence to determine where the WHERE clause must occur in the statement. In AQL, clauses execute from left to right, so the position of a FILTER clause in the query determines its precedence.

Despite such differences, anyone with an SQL background should have no difficulty in learning AQL. If you run into any problems, we have a table below showing SQL functions and commands with their AQL equivalents.

Terminology

Below is a table with the terms of both systems.

SQLAQL
databasedatabase
tablecollection
rowdocument
columnattribute
table joinscollection joins
primary keyprimary key (automatically present on _key attribute)
indexindex

large left background img min

Terminology

Below is a table with the terms of both systems.

SQLAQL
databasedatabase
tablecollection
rowdocument
columnattribute
table joinscollection joins
primary keyprimary key (automatically present on _key attribute)
indexindex

INSERT

The INSERT keyword adds new documents to a collection.  It uses the following syntax:

INSERT document INTO collection options

Inserting a single row / document

SQL:

INSERT INTO users (name, gender) 
  VALUES ("John Doe", "m");

AQL:

INSERT { name: "John Doe", gender: "m" } 
  INTO users
right blob img min

Inserting a single row / document

SQL:

INSERT INTO users (name, gender) 
  VALUES ("John Doe", "m");

AQL:

INSERT { name: "John Doe", gender: "m" } 
  INTO users

Inserting multiple rows / documents

SQL:

INSERT INTO users (name, gender) 
  VALUES ("John Doe", "m"), 
("Jane Smith", "f");

AQL:

FOR user IN [ 
  { name: "John Doe", gender: "m" }, 
  { name: "Jane Smith", gender: "f" } 
]
  INSERT user INTO users 
  INTO users

Inserting multiple rows / documents

SQL:

INSERT INTO users (name, gender) 
  VALUES ("John Doe", "m"), 
("Jane Smith", "f");

AQL:

FOR user IN [ 
  { name: "John Doe", gender: "m" }, 
  { name: "Jane Smith", gender: "f" } 
]
  INSERT user INTO users 
  INTO users

Inserting rows / documents from a table / collection

SQL:

INSERT INTO backup (uid, name, gender) 
  SELECT uid, name, gender 
  FROM users 
  WHERE active = 1;

AQL:

FOR user IN users
  FILTER user.active == 1
  INSERT user INTO backup
background img

Inserting rows / documents from a table / collection

SQL:

INSERT INTO backup (uid, name, gender) 
  SELECT uid, name, gender 
  FROM users 
  WHERE active = 1;

AQL:

FOR user IN users
  FILTER user.active == 1
  INSERT user INTO backup

Generating test rows / documents

SQL:

Use scripts or stored procedures or populate from an existing table.

AQL:

FOR i IN 1..1000
  INSERT {
    name: CONCAT("test", i),
    gender: (i % 2 == 0 ? "f" : "m")
  }
  INTO users

Generating test rows / documents

SQL:

INSERT INTO backup (uid, name, gender) 
  SELECT uid, name, gender 
  FROM users 
  WHERE active = 1;

AQL:

FOR i IN 1..1000
  INSERT {
    name: CONCAT("test", i),
    gender: (i % 2 == 0 ? "f" : "m")
  }
  INTO users

New and eager to try out ArangoDB? Start your free 2-weeks trial with ArangoDB ArangoGraph: Cloud Service for ArangoDB and run the database directly in the cloud.

UPDATE

The UPDATE keyword partially modifies documents in a collection. There are two syntaxes available for this operation:

UPDATE document IN collection options
UPDATE keyExpression WITH document IN collection options

Updating a single row / document

SQL:

UPDATE users 
  SET name = "John Smith"
  WHERE id = 1;

AQL:

UPDATE { _key: "1" }
  WITH { name: "John Smith" }
  IN users
large right background img

Updating a single row / document

SQL:

UPDATE users 
  SET name = "John Smith"
  WHERE id = 1;

AQL:

UPDATE { _key: "1" }
  WITH { name: "John Smith" }
  IN users

Adding a new column / attribute with a default value

SQL:

ALTER TABLE users 
  ADD COLUMN numberOfLogins 
  INTEGER NOT NULL default 0;

AQL:

FOR user IN users
  UPDATE user 
    WITH { numberOfLogins: 0 } IN users

Adding a new column / attribute with a default value

SQL:

ALTER TABLE users 
  ADD COLUMN numberOfLogins 
  INTEGER NOT NULL default 0;

AQL:

FOR user IN users
  UPDATE user 
    WITH { numberOfLogins: 0 } IN users

Adding a new column / attribute with a calculated value

SQL:

ALTER TABLE users 
  ADD COLUMN numberOfLogins INTEGER 
             NOT NULL default 0;
UPDATE users 
  SET numberOfLogins = (
    SELECT COUNT(*) FROM logins 
    WHERE user = users.id
  ) 
  WHERE active = 1;

AQL:

FOR user IN users
  FILTER user.active == 1
    UPDATE user 
      WITH { 
        numberOfLogins: LENGTH(
          FOR login IN logins 
            FILTER login.user == user._key 
            COLLECT WITH COUNT INTO numLogins 
            RETURN numLogins 
        )
      } IN userss
background img

Adding a new column / attribute with a calculated value

SQL:

ALTER TABLE users 
  ADD COLUMN numberOfLogins INTEGER 
             NOT NULL default 0;
UPDATE users 
  SET numberOfLogins = (
    SELECT COUNT(*) FROM logins 
    WHERE user = users.id
  ) 
  WHERE active = 1;

AQL:

FOR user IN users
  FILTER user.active == 1
    UPDATE user 
      WITH { 
        numberOfLogins: LENGTH(
          FOR login IN logins 
            FILTER login.user == user._key 
            COLLECT WITH COUNT INTO numLogins 
            RETURN numLogins 
        )
      } IN userss

Adding optional columns / attributes

SQL:

ALTER TABLE users 
  ADD COLUMN isImportantUser 
             INTEGER default NULL,
  ADD COLUMN dateBecameImportant 
             INTEGER default NULL;
 
UPDATE users 
  SET isImportantUser = 1, 
      dateBecameImportant = UNIX_TIMESTAMP()
  WHERE isImportantUser IS NULL AND (
    SELECT COUNT(*) FROM logins 
      WHERE user = user.id
  ) > 50;

*Not directly possible, must set column to default value (e.g. NULL) for rows that do not qualify.

AQL:

LET date = DATE_NOW()
  FOR user IN users
    FILTER user.isImportantUser == null
    LET numberOfLogins = (
      FOR login IN logins 
        FILTER login.user == user._key
        COLLECT WITH COUNT INTO numLogins
        RETURN numLogins
      )
    FILTER numberOfLogins > 50
    UPDATE user 
      WITH { 
        isImportantUser: 1, 
        dateBecameImportant: date 
      } 
      IN users

Adding optional columns / attributes

SQL:

ALTER TABLE users 
  ADD COLUMN isImportantUser 
             INTEGER default NULL,
  ADD COLUMN dateBecameImportant 
             INTEGER default NULL;
 
UPDATE users 
  SET isImportantUser = 1, 
      dateBecameImportant = UNIX_TIMESTAMP()
  WHERE isImportantUser IS NULL AND (
    SELECT COUNT(*) FROM logins 
      WHERE user = user.id
  ) > 50;

*Not directly possible, must set column to default value (e.g. NULL) for rows that do not qualify.

AQL:

LET date = DATE_NOW()
  FOR user IN users
    FILTER user.isImportantUser == null
    LET numberOfLogins = (
      FOR login IN logins 
        FILTER login.user == user._key
        COLLECT WITH COUNT INTO numLogins
        RETURN numLogins
      )
    FILTER numberOfLogins > 50
    UPDATE user 
      WITH { 
        isImportantUser: 1, 
        dateBecameImportant: date 
      } 
      IN users
right blob img min

Removing a column / attribute

SQL:

ALTER TABLE users
  DROP COLUMN numberOfLogins;

AQL:

FOR user IN users
  UPDATE user WITH { numberOfLogins: null } 
    IN users 
  OPTIONS { keepNull: false }

Removing a column / attribute

SQL:

ALTER TABLE users
  DROP COLUMN numberOfLogins;

AQL:

FOR user IN users
  UPDATE user WITH { numberOfLogins: null } 
    IN users 
  OPTIONS { keepNull: false }

Removing a column / attribute only for some rows / documents

SQL:

UPDATE users 
  SET isImportantUser = NULL, 
    dateBecameImportant = NULL
  WHERE isImportantUser = 1 AND active = 0;

*Not directly possible, must set column to default value (e.g. NULL) for rows that qualify.

AQL:

FOR user IN users
  FILTER user.isImportantUser == 1 AND 
         user.active == 0
    UPDATE user 
      WITH { 
        isImportantUser: null, 
        dateBecameImportant: null 
      } 
      IN users 
    OPTIONS { keepNull: false }
background img

Removing a column / attribute only for some rows / documents

SQL:

UPDATE users 
  SET isImportantUser = NULL, 
    dateBecameImportant = NULL
  WHERE isImportantUser = 1 AND active = 0;

*Not directly possible, must set column to default value (e.g. NULL) for rows that qualify.

AQL:

FOR user IN users
  FILTER user.isImportantUser == 1 AND 
         user.active == 0
    UPDATE user 
      WITH { 
        isImportantUser: null, 
        dateBecameImportant: null 
      } 
      IN users 
    OPTIONS { keepNull: false }

REPLACE

The REPLACE keyword completely modifies documents in a collection. There are two syntaxes available for this operation:

REPLACE document IN collection options
REPLACE keyExpression WITH document IN collection options

REPLACE

The REPLACE keyword completely modifies documents in a collection. There are two syntaxes available for this operation:

REPLACE document IN collection options
REPLACE keyExpression WITH document IN collection options

Replacing a single row / document

SQL:

2
3
REPLACE INTO users (name, gender) 
  VALUES ("Jane Smith", "f")
  WHERE id = 1;

AQL:

REPLACE { _key: "1" }
  WITH {
    name: "Jane Smith",
    gender: "f"
  }
  IN users

Replacing a single row / document

SQL:

2
3
REPLACE INTO users (name, gender) 
  VALUES ("Jane Smith", "f")
  WHERE id = 1;

AQL:

REPLACE { _key: "1" }
  WITH {
    name: "Jane Smith",
    gender: "f"
  }
  IN users
right blob img min

Replacing multiple rows / documents in a table / collection

SQL:

REPLACE INTO users (name, gender)
  SELECT name, gender FROM backup

AQL:

FOR user IN backup
  REPLACE user 
    WITH { 
      name: backup.name, 
      gender: backup.gender 
    }
    IN users

Replacing multiple rows / documents in a table / collection

SQL:

REPLACE INTO users (name, gender)
  SELECT name, gender FROM backup

AQL:

FOR user IN backup
  REPLACE user 
    WITH { 
      name: backup.name, 
      gender: backup.gender 
    }
    IN users

DELETE / REMOVE

SQL uses DELETE statements to remove rows from a table. In AQL, the REMOVE keyword allows you to remove documents from a collection.

DELETE / REMOVE

SQL uses DELETE statements to remove rows from a table. In AQL, the REMOVE keyword allows you to remove documents from a collection.

background img

Deleting a single row / document

SQL:

DELETE FROM users
  WHERE id = 1;

AQL:

REMOVE { _key:"1" } 
  IN users

Deleting a single row / document

SQL:

DELETE FROM users
  WHERE id = 1;

AQL:

REMOVE { _key:"1" } 
  IN users

Deleting multiple rows / documents

SQL:

DELETE FROM users
  WHERE active = 1;

AQL:

FOR user IN users
  FILTER user.active == 1
  REMOVE user IN users

Deleting multiple rows / documents

SQL:

DELETE FROM users
  WHERE active = 1;

AQL:

FOR user IN users
  FILTER user.active == 1
  REMOVE user IN users

Queries

When you want to retrieve rows from a table in SQL, you query the database with a SELECT statement. In AQL, you query documents from a collection using the FOR and RETURN keywords.

Here, FOR iterates over documents in a collection. RETURN determines what the query returns to the client.

large right background img

Queries

When you want to retrieve rows from a table in SQL, you query the database with a SELECT statement. In AQL, you query documents from a collection using the FOR and RETURN keywords.

Here, FOR iterates over documents in a collection. RETURN determines what the query returns to the client.

Selecting all rows / documents from a table / collection, with all columns / attributes

SQL:

SELECT * 
  FROM users;

AQL:

FOR user IN users
  RETURN user

Selecting all rows / documents from a table / collection, with all columns / attributes

SQL:

SELECT * 
  FROM users;

AQL:

FOR user IN users
  RETURN user
background img

Filtering rows / documents from a table / collection, with projection

SQL:

SELECT CONCAT(firstName, " ", lastName) 
  AS name, gender FROM users
  WHERE active = 1;

AQL:

FOR user IN users
  FILTER user.active == 1
  RETURN {
    name: CONCAT(user.firstName, " ",
                 user.lastName),
    gender: user.gender
  }

Filtering rows / documents from a table / collection, with projection

SQL:

SELECT CONCAT(firstName, " ", lastName) 
  AS name, gender FROM users
  WHERE active = 1;

AQL:

FOR user IN users
  FILTER user.active == 1
  RETURN {
    name: CONCAT(user.firstName, " ",
                 user.lastName),
    gender: user.gender
  }

Sorting rows / documents from a table / collection

SQL:


SELECT * FROM users
  WHERE active = 1
  ORDER BY name, gender;

AQL:

FOR user IN users
  FILTER user.active == 1
  SORT user.name, user.gender
  RETURN user

Sorting rows / documents from a table / collection

SQL:


SELECT * FROM users
  WHERE active = 1
  ORDER BY name, gender;

AQL:

FOR user IN users
  FILTER user.active == 1
  SORT user.name, user.gender
  RETURN user
right blob img min

AGGREGATION

There are a series of functions and clauses in both SQL and AQL to group or further refine the result-set to get the information you need. For instance, counting documents, finding the smallest or largest value, and so on.

AGGREGATION

There are a series of functions and clauses in both SQL and AQL to group or further refine the result-set to get the information you need. For instance, counting documents, finding the smallest or largest value, and so on.

Counting rows / documents in a table / collection

Both SQL and AQL can count the rows or documents in the result-set and tell you how many it finds. AQL manages counts using the WITH keyword to count the documents into a return variable.

SQL:

SELECT gender, COUNT(*) AS number FROM users
  WHERE active = 1
  GROUP BY gender;

AQL:

FOR user IN users
  FILTER user.active == 1
  COLLECT gender = user.gender 
    WITH COUNT INTO number
  RETURN { 
    gender: gender, 
    number: number 
  }

Counting rows / documents in a table / collection

Both SQL and AQL can count the rows or documents in the result-set and tell you how many it finds. AQL manages counts using the WITH keyword to count the documents into a return variable.

SQL:

SELECT gender, COUNT(*) AS number FROM users
  WHERE active = 1
  GROUP BY gender;

AQL:

FOR user IN users
  FILTER user.active == 1
  COLLECT gender = user.gender 
    WITH COUNT INTO number
  RETURN { 
    gender: gender, 
    number: number 
  }
background img

Grouping rows / documents in a table / collection

In SQL, the GROUP BY clauses collects the result-set according to the given column. AQL replaces this with the COLLECT keyword.

SQL:

SELECT YEAR(dateRegister) AS year, 
       MONTH(dateRegister) AS month, 
       COUNT(*) AS number 
  FROM users
  WHERE active = 1
  GROUP BY year, month
  HAVING number > 20;

AQL:

FOR user IN users
  FILTER user.active == 1
  COLLECT
    year = DATE_YEAR(user.dateRegistered), 
    month = DATE_MONTH(user.dateRegistered) 
    WITH COUNT INTO number
    FILTER number > 20
    RETURN { 
      year: year, 
      month: month, 
      number: number 
    }

Grouping rows / documents in a table / collection

In SQL, the GROUP BY clauses collects the result-set according to the given column. AQL replaces this with the COLLECT keyword.

SQL:

SELECT YEAR(dateRegister) AS year, 
       MONTH(dateRegister) AS month, 
       COUNT(*) AS number 
  FROM users
  WHERE active = 1
  GROUP BY year, month
  HAVING number > 20;

AQL:

FOR user IN users
  FILTER user.active == 1
  COLLECT
    year = DATE_YEAR(user.dateRegistered), 
    month = DATE_MONTH(user.dateRegistered) 
    WITH COUNT INTO number
    FILTER number > 20
    RETURN { 
      year: year, 
      month: month, 
      number: number 
    }

Minimum, maximum calculation of rows / documents in a table / collection

Both SQL and AQL use functions to find the minimum and maximum values for a given field. In AQL, it’s handled with the COLLECT keyword.

SQL:

SELECT MIN(dateRegistered) AS minDate, 
  MAX(dateRegistered) AS maxDate 
  FROM users
    WHERE active = 1;

AQL:

FOR user IN users
  FILTER user.active == 1
  COLLECT AGGREGATE
    minDate = MIN(user.dateRegistered),
    maxDate = MAX(user.dateRegistered)
  RETURN { minDate, maxDate }
right blob img min

Minimum, maximum calculation of rows / documents in a table / collection

Both SQL and AQL use functions to find the minimum and maximum values for a given field. In AQL, it’s handled with the COLLECT keyword.

SQL:

SELECT MIN(dateRegistered) AS minDate, 
  MAX(dateRegistered) AS maxDate 
  FROM users
    WHERE active = 1;

AQL:

FOR user IN users
  FILTER user.active == 1
  COLLECT AGGREGATE
    minDate = MIN(user.dateRegistered),
    maxDate = MAX(user.dateRegistered)
  RETURN { minDate, maxDate }

Building horizontal lists

SQL:

UPDATE users 
 SELECT gender, GROUP_CONCAT(id) AS userIds 
  FROM users
    WHERE active = 1
    GROUP BY gender;

*Not really applicable – use either a concatenated string column or a special datatype (non-portable).

AQL:

FOR user IN users
FOR user IN users
  FILTER user.active == 1
  COLLECT gender = user.gender 
    INTO usersByGender
  RETURN { 
    gender: gender, 
    userIds: usersByGender[*].user._key
  }

Building horizontal lists

SQL:

UPDATE users 
 SELECT gender, GROUP_CONCAT(id) AS userIds 
  FROM users
    WHERE active = 1
    GROUP BY gender;

*Not really applicable – use either a concatenated string column or a special datatype (non-portable).

AQL:

FOR user IN users
FOR user IN users
  FILTER user.active == 1
  COLLECT gender = user.gender 
    INTO usersByGender
  RETURN { 
    gender: gender, 
    userIds: usersByGender[*].user._key
  }
background img

JOINS

Similar to joins in relational databases, ArangoDB has its own implementation of JOINS. Coming from an SQL background, you may find the AQL syntax very different from your expectations.

JOINS

Similar to joins in relational databases, ArangoDB has its own implementation of JOINS. Coming from an SQL background, you may find the AQL syntax very different from your expectations.

Inner join

SQL:

SELECT * FROM users
  INNER JOIN friends 
  ON (friends.user = users.id);
  

AQL:

An inner join can be expressed easily in AQL by nesting FOR loops and using FILTER statements:

FOR user IN users 
  FOR friend IN friends
    FILTER friend.user == user._key
    RETURN MERGE(user, friend)
    

Note: in AQL the preferred way is to return the document parts from the different collections in individual sub-attributes to avoid attribute name conflicts, e.g.:

FOR user IN users 
  FOR friend IN friends
    FILTER friend.user == user._key
    RETURN { user: user, friend: friend }

It is also possible to return the matching documents in a horizontal list:

FOR user IN users 
  RETURN { 
    user: user, 
    friends: (
      FOR friend IN friends
        FILTER friend.user == user._key
        RETURN friend
    )
  }

Minimum, maximum calculation of rows / documents in a table / collection

SQL:

SELECT * FROM users
  INNER JOIN friends 
  ON (friends.user = users.id);

AQL:

An inner join can be expressed easily in AQL by nesting FOR loops and using FILTER statements:

FOR user IN users 
  FOR friend IN friends
    FILTER friend.user == user._key
    RETURN MERGE(user, friend)

Note: in AQL the preferred way is to return the document parts from the different collections in individual sub-attributes to avoid attribute name conflicts, e.g.:

FOR user IN users 
  FOR friend IN friends
    FILTER friend.user == user._key
    RETURN { user: user, friend: friend }

It is also possible to return the matching documents in a horizontal list:

FOR user IN users 
  RETURN { 
    user: user, 
    friends: (
      FOR friend IN friends
        FILTER friend.user == user._key
        RETURN friend
    )
  }}
right blob img min

Outer join

SQL:

SELECT * FROM users
  LEFT JOIN friends 
    ON (friends.user = users.id);

AQL:

Outer joins are not directly supported in AQL, but can be implemented using subqueries:

FOR user IN users 
  LET friends = (
    FOR friend IN friends
      FILTER friend.user == user._key
      RETURN friend
  )
  FOR friendToJoin IN (
    LENGTH(friends) > 0 ? friends :
      [ { /* no match exists */ } ]
    )
    RETURN { 
      user: user,
      friend: friend
    }

Outer join

SQL:

SELECT * FROM users
  LEFT JOIN friends 
    ON (friends.user = users.id);

AQL:

Outer joins are not directly supported in AQL, but can be implemented using subqueries:

FOR user IN users 
  LET friends = (
    FOR friend IN friends
      FILTER friend.user == user._key
      RETURN friend
  )
  FOR friendToJoin IN (
    LENGTH(friends) > 0 ? friends :
      [ { /* no match exists */ } ]
    )
    RETURN { 
      user: user,
      friend: friend
    }
background img

In the main, AQL is a declarative language. Queries express what results you want but not how you want to get there. AQL aims to be human-readable, therefore uses keywords from the English language.

It also aims to be client independent, meaning that the language and syntax are the same for all clients, no matter what programming language the clients use. Additionally, it supports complex query patterns and the various data models ArangoDB offers.

AQL also supports several aggregation and string functions. For more information, see AQL Functions.

6 Comments

Posted by CoDEmanX on  | | Anthony rsz img
AQL also supports INSERT ... INTO in addition to INSERT ... IN, which is not only grammatically correct, but also even closer to SQL. In fact, IN and INTO can be used interchangeably in UPDATE, REPLACE and REMOVE statements.v2.7 features Object Literal Simplification, which can be used to shorten some of above queries and get them closer to SQL as well.
Posted by Sooraj T on  | | comments img
Thank you .. This article has helped me to understand how AQL queries work in Arangodb
Posted by ArangoDB database on  | | comments dummyImage
We first had the name AvocadoDB but some other software company complained and we switched to the one and only ArangoDB 🙂

Posted by Artem on  | |comments dummyImage
Do you have construct like “case when” in oracle?

Posted by kk on  | | comments dummyImage
I want a row_number() kind of functionality in ArangoDB.

Posted by Simran Spiller on  | | comments dummyImage
@kk What would you use ROW_NUMBER() for? Simply to enumerate the results? That can be done on client-side very easily. Or to get a subset of results, like with LIMIT and OFFSET in some SQL dialects, e.g. to implement pagination? There’s the LIMIT operation in AQL which let’s you do this, but keep in mind that you should SORT the results or it won’t be stable.

6 Comments

Posted by CoDEmanX on  | | Anthony rsz img
AQL also supports INSERT ... INTO in addition to INSERT ... IN, which is not only grammatically correct, but also even closer to SQL. In fact, IN and INTO can be used interchangeably in UPDATE, REPLACE and REMOVE statements.v2.7 features Object Literal Simplification, which can be used to shorten some of above queries and get them closer to SQL as well.

Posted by Sooraj T on  | | comments img
Thank you .. This article has helped me to understand how AQL queries work in Arangodb

Posted by ArangoDB database on  | | comments dummyImage
We first had the name AvocadoDB but some other software company complained and we switched to the one and only ArangoDB 🙂

Posted by Artem on  | |comments dummyImage
Do you have construct like “case when” in oracle?

Posted by kk on  | | comments dummyImage
I want a row_number() kind of functionality in ArangoDB.

Posted by Simran Spiller on  | | comments dummyImage
@kk What would you use ROW_NUMBER() for? Simply to enumerate the results? That can be done on client-side very easily. Or to get a subset of results, like with LIMIT and OFFSET in some SQL dialects, e.g. to implement pagination? There’s the LIMIT operation in AQL which let’s you do this, but keep in mind that you should SORT the results or it won’t be stable.