# Exact Online

### SELECT Statements <a href="#default" id="default"></a>

A SELECT statement can consist of the following basic clauses.

* SELECT
* INTO
* FROM
* JOIN
* WHERE
* GROUP BY
* HAVING
* UNION
* ORDER BY
* LIMIT

### SELECT Syntax

The following syntax diagram outlines the syntax supported by the SQL engine of the provider:

\
SELECT {

&#x20; \[ TOP \<numeric\_literal> | DISTINCT ]

&#x20; {

&#x20;   \*

&#x20;   \| {

&#x20;       \<expression> \[ \[ AS ] \<column\_reference> ]

&#x20;       \| { \<table\_name> | \<correlation\_name> } .\*

&#x20;     } \[ , ... ]

&#x20; }

&#x20; \[ INTO csv:// \[ filename= ] \<file\_path> \[ ;delimiter=tab ] ]

&#x20; {

&#x20;   FROM \<table\_reference> \[ \[ AS ] \<identifier> ]

&#x20; } \[ , ... ]

&#x20; \[ \[&#x20;

&#x20;     INNER | { { LEFT | RIGHT | FULL } \[ OUTER ] }

&#x20;   ] JOIN \<table\_reference> \[ ON \<search\_condition> ] \[ \[ AS ] \<identifier> ]

&#x20; ] \[ ... ]

&#x20; \[ WHERE \<search\_condition> ]

&#x20; \[ GROUP BY \<column\_reference> \[ , ... ]

&#x20; \[ HAVING \<search\_condition> ]

&#x20; \[ UNION \[ ALL ] \<select\_statement> ]

&#x20; \[

&#x20;   ORDER BY

&#x20;   \<column\_reference> \[ ASC | DESC ] \[ NULLS FIRST | NULLS LAST ]

&#x20; ]

&#x20; \[

&#x20;   LIMIT \<expression>

&#x20;   \[

&#x20;     { OFFSET | , }

&#x20;     \<expression>

&#x20;   ]

&#x20; ]

} | SCOPE\_IDENTITY()

&#x20;

\<expression> ::=

&#x20; \| \<column\_reference>

&#x20; \| @ \<parameter>

&#x20; \| ?

&#x20; \| COUNT( \* | { \[ DISTINCT ] \<expression> } )

&#x20; \| { AVG | MAX | MIN | SUM | COUNT } ( \<expression> )

&#x20; \| NULLIF ( \<expression> , \<expression> )

&#x20; \| COALESCE ( \<expression> , ... )

&#x20; \| CASE \<expression>

&#x20;     WHEN { \<expression> | \<search\_condition> } THEN { \<expression> | NULL } \[ ... ]

&#x20;   \[ ELSE { \<expression> | NULL } ]

&#x20;   END

&#x20; \| \<literal>

&#x20; \| \<sql\_function>

&#x20;

\<search\_condition> ::=

&#x20; {

&#x20;   \<expression> { = | > | < | >= | <= | <> | != | LIKE | NOT LIKE | IN | NOT IN | IS NULL | IS NOT NULL | AND | OR | CONTAINS | BETWEEN } \[ \<expression> ]

&#x20; } \[ { AND | OR } ... ]&#x20;

#### Examples

1. Return all columns:<br>

   | `SELECT * FROM Accounts` |
   | ------------------------ |
2. Rename a column:<br>

   | `SELECT [Name] AS MY_Name FROM Accounts` |
   | ---------------------------------------- |
3. Cast a column's data as a different data type:<br>

   | `SELECT CAST(AnnualRevenue AS VARCHAR) AS Str_AnnualRevenue FROM Accounts` |
   | -------------------------------------------------------------------------- |
4. Search data:<br>

   | `SELECT * FROM Accounts WHERE City = 'Raleigh'` |
   | ----------------------------------------------- |
5. Return the number of items matching the query criteria:<br>

   | `SELECT COUNT(*) AS MyCount FROM Accounts` |
   | ------------------------------------------ |
6. Return the number of unique items matching the query criteria:<br>

   | `SELECT COUNT(DISTINCT Name) FROM Accounts` |
   | ------------------------------------------- |
7. Return the unique items matching the query criteria:<br>

   | `SELECT DISTINCT Name FROM Accounts` |
   | ------------------------------------ |
8. Summarize data:<br>

   | `SELECT Name, MAX(AnnualRevenue) FROM Accounts GROUP BY Name` |
   | ------------------------------------------------------------- |

   See Aggregate Functions below for details.
9. Retrieve data from multiple tables.<br>

   | `SELECT Accounts.Name, Contacts.FullName FROM Accounts, Contacts WHERE Accounts.ID=Contacts.Account` |
   | ---------------------------------------------------------------------------------------------------- |

   See JOIN Queries below for details.
10. Sort a result set in ascending order:<br>

    | `SELECT Id, Name FROM Accounts  ORDER BY Name ASC` |
    | -------------------------------------------------- |
11. Restrict a result set to the specified number of rows:<br>

    | `SELECT Id, Name FROM Accounts LIMIT 10` |
    | ---------------------------------------- |
12. Parameterize a query to pass in inputs at execution time. This enables you to create prepared statements and mitigate SQL injection attacks.<br>

    | `SELECT * FROM Accounts WHERE City = @param` |
    | -------------------------------------------- |

### Aggregate Functions <a href="#count" id="count"></a>

#### COUNT <a href="#count" id="count"></a>

Returns the number of rows matching the query criteria.<br>

| `SELECT COUNT(*) FROM Accounts WHERE City = 'Raleigh'` |
| ------------------------------------------------------ |

#### COUNT(DISTINCT) <a href="#countdistinct" id="countdistinct"></a>

Returns the number of distinct, non-null field values matching the query criteria.<br>

| `SELECT COUNT(DISTINCT Id) AS DistinctValues FROM Accounts WHERE City = 'Raleigh'` |
| ---------------------------------------------------------------------------------- |

#### AVG <a href="#avg" id="avg"></a>

Returns the average of the column values.<br>

| `SELECT Name, AVG(AnnualRevenue) FROM Accounts WHERE City = 'Raleigh'`  `GROUP BY Name` |
| --------------------------------------------------------------------------------------- |

#### MIN <a href="#min" id="min"></a>

Returns the minimum column value.<br>

| `SELECT MIN(AnnualRevenue), Name FROM Accounts WHERE City = 'Raleigh'` `GROUP BY Name` |
| -------------------------------------------------------------------------------------- |

#### MAX <a href="#max" id="max"></a>

Returns the maximum column value.<br>

| `SELECT Name, MAX(AnnualRevenue) FROM Accounts WHERE City = 'Raleigh'` `GROUP BY Name` |
| -------------------------------------------------------------------------------------- |

#### SUM <a href="#sum" id="sum"></a>

Returns the total sum of the column values.<br>

| `SELECT SUM(AnnualRevenue) FROM Accounts WHERE City = 'Raleigh'` |
| ---------------------------------------------------------------- |

### JOIN Queries <a href="#default" id="default"></a>

The Provider for Exact Online supports standard SQL joins like the following examples.

#### Inner Join

An inner join selects only rows from both tables that match the join condition:<br>

| `SELECT Accounts.Name, Contacts.FullName FROM Accounts, Contacts WHERE Accounts.ID=Contacts.Account` |
| ---------------------------------------------------------------------------------------------------- |

#### Left Join

A left join selects all rows in the FROM table and only matching rows in the JOIN table:<br>

| `SELECT Accounts.Name, Contacts.FullName FROM Accounts LEFT OUTER JOIN Contacts ON Accounts.ID=Contacts.Account` |
| ---------------------------------------------------------------------------------------------------------------- |

### Date Literal Functions <a href="#default" id="default"></a>

The following date literal functions can be used to filter date fields using relative intervals. Note that while the <, >, and = operators are supported for these functions, <= and >= are not.

#### L\_TODAY() <a href="#ltoday" id="ltoday"></a>

The current day.<br>

| `SELECT * FROM MyTable WHERE MyDateField = L_TODAY()` |
| ----------------------------------------------------- |

#### L\_YESTERDAY() <a href="#lyesterday" id="lyesterday"></a>

The previous day.<br>

| `SELECT * FROM MyTable WHERE MyDateField = L_YESTERDAY()` |
| --------------------------------------------------------- |

#### L\_TOMORROW() <a href="#ltomorrow" id="ltomorrow"></a>

The following day.<br>

| `SELECT * FROM MyTable WHERE MyDateField = L_TOMORROW()` |
| -------------------------------------------------------- |

#### L\_LAST\_WEEK() <a href="#llastweek" id="llastweek"></a>

Every day in the preceding week.<br>

| `SELECT * FROM MyTable WHERE MyDateField = L_LAST_WEEK()` |
| --------------------------------------------------------- |

#### L\_THIS\_WEEK() <a href="#lthisweek" id="lthisweek"></a>

Every day in the current week.<br>

| `SELECT * FROM MyTable WHERE MyDateField = L_THIS_WEEK()` |
| --------------------------------------------------------- |

#### L\_NEXT\_WEEK() <a href="#lnextweek" id="lnextweek"></a>

Every day in the following week.<br>

| `SELECT * FROM MyTable WHERE MyDateField = L_NEXT_WEEK()` |
| --------------------------------------------------------- |

Also available:

* L\_LAST/L\_THIS/L\_NEXT MONTH
* L\_LAST/L\_THIS/L\_NEXT QUARTER
* L\_LAST/L\_THIS/L\_NEXT YEAR

#### L\_LAST\_N\_DAYS(n) <a href="#llastndaysn" id="llastndaysn"></a>

The previous n days, excluding the current day.<br>

| `SELECT * FROM MyTable WHERE MyDateField = L_LAST_N_DAYS(3)` |
| ------------------------------------------------------------ |

#### L\_NEXT\_N\_DAYS(n) <a href="#lnextndaysn" id="lnextndaysn"></a>

The following n days, including the current day.<br>

| `SELECT * FROM MyTable WHERE MyDateField = L_NEXT_N_DAYS(3)` |
| ------------------------------------------------------------ |

Also available:

* L\_LAST/L\_NEXT\_90\_DAYS

#### L\_LAST\_N\_WEEKS(n) <a href="#llastnweeksn" id="llastnweeksn"></a>

Every day in every week, starting n weeks before current week, and ending in the previous week.<br>

| `SELECT * FROM MyTable WHERE MyDateField = L_LAST_N_WEEKS(3)` |
| ------------------------------------------------------------- |

#### L\_NEXT\_N\_WEEKS(n) <a href="#lnextnweeksn" id="lnextnweeksn"></a>

Every day in every week, starting the following week, and ending n weeks in the future.<br>

| `SELECT * FROM MyTable WHERE MyDateField = L_NEXT_N_WEEKS(3)` |
| ------------------------------------------------------------- |

Also available:

* L\_LAST/L\_NEXT\_N\_MONTHS(n)
* L\_LAST/L\_NEXT\_N\_QUARTERS(n)
* L\_LAST/L\_NEXT\_N\_YEARS(n)
