_This page explains select statements with a static structure. If you want to learn about constructing select statements at runtime, you should still read this page first and then move on to [dynamic select statements](Dynamic-Select.md)._
Lets assume we have a table representing
```SQL
CREATE TABLE foo (
id bigint,
name varchar(50),
hasFun bool
);
```
(This is SQL for brevity, not C++, see [here](Tables.md) for details on how to define types representing the tables and columns you want to work with)
Lets also assume we have an object `db` representing a connection to your [database](Database.md).
# A Basic example
This shows how you can select some data from table and iterate over the results:
```C++
for (const auto& row : db(select(foo.name, foo.hasFun)
.from(foo)
.where(foo.id > 17 and foo.name.like("%bar%"))))
{
if (row.name.is_null())
std::cerr << "name is null" <<std::endl;
else
std::string name = row.name; // string-like fields are implicitly convertible to string
bool hasFun = row.hasFun; // bool fields are implicitly convertible to bool
}
```
So, what's happening here? Lets ignore the gory details for a moment. Well, there is a select statement.
```C++
select(foo.name, foo.hasFun)
.from(foo)
.where(foo.id > 17 and foo.name.like("%bar%"))
```
It selects two columns `name` and `hasFun` from table `foo` for rows which match the criteria given in the where condition. That's about as close to _real_ SQL as it can get...
The select expression is fed into the call operator of the connection object `db`. This method sends the select statement to the database and returns an object representing the results. In the case of select statements, the result object represents zero or more rows.
One way of accessing the rows is to iterate over them in a range-based for loop.
```C++
for (const auto& row : ...)
```
Ok, so the variable row is an object that represents a single result row. You really want to use `auto` here, because you don't want to write down the actual type. Trust me. But the wonderful thing about the `row` object is that it has appropriately named and typed members representing the columns you selected. This is one of the utterly cool parts of this library.
# The Select Statement
## Select
The `select` method takes zero or more named expression arguments.
Named expressions are expressions with a name. No surprise there. But what kind of expressions have a name? Table columns, for instance. In our example, that would be `foo.id`, `foo.name` and `foo.hasFun`. Most [function](Functions.md) calls also result in named expressions, like `count(foo.id)`.
So what about unnamed expressions? Results of binary operators like `(foo.id + 17) * 4` have no name. But you can give them a name using the `as(alias)` method. The easiest way is to use a named expression as alias, for instance `((foo.id + 17) * 4).as(foo.id)`, e.g.
```C++
for (const auto& row : db(select(((foo.id + 17) * 4).as(foo.id)).from(tab)))
{
std::cout <<row.id<<std::endl;
}
```
Another option is to define an alias like this:
```C++
SQLPP_ALIAS_PROVIDER(total);
for (const auto& row : db(select(sum(id).as(total)).as(foo.id)).from(tab)))
Using aliases also comes in handy when you join tables and have several columns of the same name, because no two named expressions in a select must have the same name. So if you want to do something like
All examples above called the `select()` function with one or more arguments, but `select()` can also be called with no arguments. In that case, the selected columns have to be added afterwards
```C++
sqlpp::select().columns(foo.id, foo.name);
```
See also [dynamic select statements](Dynamic-Select.md).
OK, so now we know how to create a select statement. But the statement does not really do anything unless we hand it over to the database:
```C++
db(select(all_of(foo)).from(foo));
```
This call returns a result object of a pretty complex type. Thus, you would normally want to use `auto`:
```C++
auto result = db(select(all_of(foo)).from(foo));
```
# Accessing The Results
The `result` object created by executing a `select` query is a container of result rows.
## Range-based For Loops
Not surprisingly, you can iterate over the rows using a range-based for-loop like this:
```C++
for (const auto& row : db(select(all_of(foo)).from(foo)))
{
std::cerr <<row.id<<std::endl;
std::cerr <<row.name<<std::endl;
}
```
Lovely, isn't it? The row objects have types specifically tailored for the select query you wrote. You can access their member by name, and these members have the expected type.
## Function-based Access
If for some reason, you don't want to use range-based for-loops, you can use `front()` and `pop_front()` on the result, like this: