Skip to main content

SQL Tables and Queries

This page uses Wasm code blocks so you can run the examples directly in the browser.

SA Engine includes a built-in main-memory local database that can be queried with the standard database query language SQL. The main use of the local database is for storing models, parameters and other meta-data. It is a relational database extended to permit objects of many different types to be stored and queried.

In this section we show how the local database can be used as a regular main-memory relational database managed by SQL statements.

Creating tables​

The create table statement creates a new database table.

Examples:

Suppose we are going to store data about departments and their properties. The first thing to do is to define a new table named Department having the two columns id and name using the create table statement:

create table Department(id Integer,      // Identifier of departments
name Charstring, // Name of department
unique(id), // Department identifiers are unique
unique(name) // Department names are unique
)
Note

The above create table is simpler than SQL's create table statement, in that columns are specified using OSQL types. SQL data types are translated to the corresponding OSQL types.

Let's create another table Person with columns id, name, income, and dept:

create table Person(id     Integer,        // Unique identifier of persons
name Charstring, // Name of person
income Real, // Income of person
dept Integer, // Department id for person
unique(id))

We create a third table Account with columns id, owner, and balance:

create table Account(id      Integer,      // Unique identifier of accounts
owner Integer, // Id of person owning account
balance Real, // Current balance
unique(id))

Populating tables​

The insert into statement populates the database by inserting rows into tables.

Examples:

Add three rows to the table Department:

insert into Department values (1, 'Toys'),
(2, 'Food'),
(3, 'Tools')

Populate the Person table with seven rows:

insert into Person values(1,"Kalle", 100.0, 2),
(2,"Ville", 360.0, 2),
(3,"Ulla", 300.0, 3),
(4,"Mats", 400.0, 1),
(5,"Anita", 585.0, 1),
(6,"Magnus", 500.0, 1),
(7,"Eva", 401.0, 3)

Create accounts and assign them to the persons owning the accounts:

insert into Account values(1,2,150.0),
(2,1,200.0),
(3,2,400.0),
(4,1,85.0),
(5,2,70.0),
(6,3,10.0),
(7,5,500.0),
(8,6,75.0),
(9,3,95.0)

Queries​

SQL queries retrieve data from tables based on search conditions using the select statement.

Examples:

Get all rows in the table Department:

select * from Department

Get the names and incomes of all persons in the database:

select name, income
from Person

Get the names of persons working in the department named 'Toys':

select p.name
from Person p, Department d
where p.dept = d.id
and d.name = 'Toys'
Note

We use the table alias names p and d as shortcuts for the tables Person and Department, respectively. This is recommended to avoid ambiguous column names from different tables when combining more than one table in the from clause. The dot operator (.) uniquely identifies a column in a table.

Get the balances of the accounts of the person named 'Ville':

select a.balance
from Account a, Person p
where p.name = 'Ville'
and a.owner = p.id

Get the names and account balances of all persons in the 'Toys' department:

select p.name, a.balance
from Person p, Department d, Account a
where p.dept = d.id
and d.name = 'Toys'
and a.owner = p.id

Pattern matching​

We may filter strings by matching them against a pattern by using the SQL operator like:

Example:

Get the names of the departments that begins with a T

select name
from Department w
where name like 'T%'

Here the two department names 'Toys' and 'Tools'are matching the pattern 'T%', A % matches any sequence of characters while a _ matches a single character.

Sorting the query result​

The order by keyword in a select statement specifies the ordering of the result rows.

Get the names and incomes of all persons ordered decreasingly by income:

select name, income
from Person
order by income desc

Get the two highest paid persons:

select name, income
from Person
order by income desc
limit 2
Note

The keyword limit restricts the number of rows (or tuples) to return from a select statement. It is not standard SQL so different vendors use different terms for this.

Get the names and incomes of those persons earning more than 400 ordered by their names:

select name, income
from Person
where income > 400
order by name

Aggregate functions​

Aggregate functions compute a single value from a bag of values in a query.

Examples:

How many persons are there in the database?

select count(*) from Person

The function count is an aggregate function, which takes a bag (i.e. set with duplicates) of values as argument and returns a single value.

What is the total sum of the incomes of all persons?

select sum(income) from Person

sum is an aggregate function too.

What is average income of all persons?

select avg(income) from Person

select avg(income) from Person

What is the median income?

select median(income) from Person
Note

The aggregate function median is not supported by standard SQL.

Count the number of accounts per person in 'Food' department:

select p.name, count(a.id)
from Person p, Department d, Account a
where d.name = 'Food'
and p.dept = d.id
and a.owner = p.id
group by p.name

Compute the total balances of accounts per person in 'Food' department:

select p.name, sum(a.balance)
from Person p, Department d, Account a
where d.name = 'Food'
and p.dept = d.id
and a.owner = p.id
group by p.name

Get the total balances of all accounts per person:

select p.name, sum(a.balance)
from Person p, Account a
where a.owner = p.id
group by p.name

Get decreasingly ordered total balances of each person in the database:

select p.name, sum(a.balance)
from Person p, Account a
where a.owner = p.id
group by p.name
order by sum(a.balance) desc

What are the lowest incomes in each department?

select d.name, min(p.income)
from Department d, Person p
where p.dept = d.id
group by d.name
order by min(p.income)

Get the two departments with highest average incomes:

select d.name, avg(p.income)
from Department d, Person p
where p.dept = d.id
group by d.name
order by avg(p.income) desc
limit 2

For each person get the name, department name, income, and total balance, ordered by total balance decreasingly:

select p.name, d.name, p.income, sum(a.balance)
from Department d, Person p, Account a
where a.owner = p.id
and p.dept = d.id
group by p.name, d.name, p.income
order by sum(a.balance) desc

Updating tables​

The update statement changes rows in a table based on some condition.

Examples:

Change the income of Kalle to 150:

update Person set income=150 where name = 'Kalle'

Increase the income with 10% for all persons whose names begin with the letter 'A':

update Person set income=income * 1.1 where name like 'A%'

Copying tables​

The insert into statement can be used for copying data between tables.

Example:

Copy data about those persons whose incomes are larger than 350 from table Person into a new table HighEarners:

create table HighEarners(id         Integer,
name Charstring,
income Real,
department Integer,
unique(id))
insert into HighEarners select * from Person where income > 350
select * from HighEarners

Removing tables​

Tables are removed by the drop table statement.

Example:

drop table Account

The next tutorial shows how to develop models, undo changes, and save the database of models on disk.