> ## Documentation Index
> Fetch the complete documentation index at: https://www.propeldata.com/llms.txt
> Use this file to discover all available pages before exploring further.

# SELECT

> The SELECT statement reference.

<div />

## Syntax

```sql theme={"system"}
[WITH expr_list|(subquery)]
SELECT [DISTINCT [ON (column1, column2, ...)]] expr_list
[FROM [db.]table | (subquery) | table_function] [FINAL]
[SAMPLE sample_coeff]
[ARRAY JOIN ...]
[GLOBAL] [ANY|ALL|ASOF] [INNER|LEFT|RIGHT|FULL|CROSS] [OUTER|SEMI|ANTI] JOIN (subquery)|table (ON <expr_list>)|(USING <column_list>)
[PREWHERE expr]
[WHERE expr]
[GROUP BY expr_list] [WITH ROLLUP|WITH CUBE] [WITH TOTALS]
[HAVING expr]
[WINDOW window_expr_list]
[QUALIFY expr]
[ORDER BY expr_list] [WITH FILL] [FROM expr] [TO expr] [STEP expr] [INTERPOLATE [(expr_list)]]
[LIMIT [offset_value, ]n BY columns]
[LIMIT [n, ]m] [WITH TIES]
[SETTINGS ...]
[UNION  ...]
[INTO OUTFILE filename [COMPRESSION type [LEVEL level]] ]
[FORMAT format]
```

## Clauses

### SELECT

The SELECT clause specifies the columns, expressions, or aggregations you want to retrieve.

```sql theme={"system"}
-- Select specific columns
SELECT column1, column2
FROM table_name;

-- Select all columns
SELECT *
FROM table_name;

-- Select with expressions
SELECT
    first_name,
    last_name,
    price * quantity as total_value
FROM table_name;
```

### FROM

The FROM clause specifies the source table(s), subquery, or table function to query from.

```sql theme={"system"}
-- Query from a table
SELECT * FROM table_name;

-- Query from a specific database
SELECT * FROM database.table_name;

-- Query from a subquery
SELECT *
FROM (
    SELECT column1, column2
    FROM table_name
    WHERE condition
) AS subquery;

-- Query using a table function
SELECT *
FROM table_function(arg1, arg2);
```

### WHERE

The WHERE clause filters rows based on specified conditions. It supports various comparison and logical operators.

```sql theme={"system"}
SELECT column1, column2
FROM table_name
WHERE
    (price > 100 AND category = 'electronics')
    OR (price > 200 AND category = 'furniture');
```

### GROUP BY

The GROUP BY clause groups rows by specified columns and is typically used with aggregate functions. Supports additional modifiers:

* WITH ROLLUP: Adds extra rows with subtotals
* WITH CUBE: Adds subtotals for all possible combinations
* WITH TOTALS: Adds a final row with totals

```sql theme={"system"}
-- Basic grouping
SELECT
    category,
    COUNT(*) as count,
    AVG(price) as avg_price
FROM products
GROUP BY category;

-- Grouping with ROLLUP
SELECT
    category,
    subcategory,
    SUM(sales)
FROM sales
GROUP BY
    category,
    subcategory
WITH ROLLUP;
```

### HAVING

The HAVING clause filters grouped results based on aggregate conditions.

```sql theme={"system"}
SELECT
    category,
    COUNT(*) as product_count,
    AVG(price) as avg_price
FROM products
GROUP BY category
HAVING
    COUNT(*) > 10
    AND AVG(price) > 100;
```

### ORDER BY

The ORDER BY clause sorts results by specified columns. Supports additional features:

* WITH FILL: Fills missing values in sorted results
* INTERPOLATE: Specifies how to interpolate missing values

```sql theme={"system"}
-- Basic sorting
SELECT *
FROM table_name
ORDER BY
    column1 DESC,
    column2 ASC;

-- Sorting with fill
SELECT
    time,
    value
FROM metrics
ORDER BY time WITH FILL
    FROM '2024-01-01'
    TO '2024-01-02'
    STEP INTERVAL 1 HOUR;
```

### JOIN

Propel supports various types of joins to combine rows from two or more tables based on a related column between them.

* **LEFT JOIN**

The LEFT JOIN returns all records from the left table (table1), and the matched records from the right table (table2). The result is NULL from the right side if there is no match.

```sql theme={"system"}
SELECT columns
FROM table1
LEFT JOIN table2
ON table1.column = table2.column;
```

* **RIGHT JOIN**

The RIGHT JOIN returns all records from the right table (table2), and the matched records from the left table (table1). The result is NULL from the left side if there is no match.

```sql theme={"system"}
SELECT columns
FROM table1
RIGHT JOIN table2
ON table1.column = table2.column;
```

* **FULL JOIN**

The FULL JOIN returns all records when there is a match in either left (table1) or right (table2) table records. If there is no match, the result contains NULL values for columns from the table without a match.

```sql theme={"system"}
SELECT columns
FROM table1
FULL JOIN table2
ON table1.column = table2.column;
```

* **INNER JOIN**

The INNER JOIN returns all records when there is a match in both left (table1) and right (table2) table records.

```sql theme={"system"}
SELECT columns
FROM table1
INNER JOIN table2
ON table1.column = table2.column;
```

### DISTINCT, UNION, and ALL

* **DISTINCT**

The DISTINCT clause is used to return only unique values in the result set.

```sql theme={"system"}
SELECT DISTINCT column1, column2, ...
FROM table_name;
```

* **UNION**

The UNION operator is used to combine the result sets of two or more SELECT statements.

```sql theme={"system"}
SELECT column1, column2, ...
FROM table1
UNION
SELECT column1, column2, ...
FROM table2;
```

* **UNION ALL**

The UNION ALL operator is used to combine the result sets of two or more SELECT statements, including duplicates.

```sql theme={"system"}
SELECT column1, column2, ...
FROM table1
UNION ALL
SELECT column1, column2, ...
FROM table2;
```

### WITH

The WITH clause is used to define a common table expression (CTE).

```sql theme={"system"}
WITH cte_name AS (
    SELECT column1, column2, ...
    FROM table_name
    WHERE condition
)
SELECT column1, column2, ...
FROM cte_name;
```

### LIMIT

The LIMIT clause controls the number of rows returned. It supports several formats:

* Basic LIMIT with optional OFFSET
* LIMIT BY to limit rows per group
* WITH TIES to include rows that match the last row

```sql theme={"system"}
-- Basic limit
SELECT *
FROM table_name
LIMIT 10;

-- Limit with offset
SELECT *
FROM table_name
LIMIT 10 OFFSET 20;

-- Limit BY
SELECT
    category,
    product_name,
    price
FROM products
LIMIT 3 BY category;  -- Return top 3 products per category

-- Limit with ties
SELECT *
FROM table_name
ORDER BY score
LIMIT 10 WITH TIES;  -- Include tied scores
```

### WINDOW

The WINDOW clause defines named window specifications for window functions.

```sql theme={"system"}
SELECT
    date,
    value,
    AVG(value) OVER w as moving_avg,
    RANK() OVER w as rank
FROM metrics
WINDOW w AS (
    PARTITION BY category
    ORDER BY date
    ROWS BETWEEN 3 PRECEDING AND CURRENT ROW
);
```

### QUALIFY

The QUALIFY clause filters results based on window functions.

```sql theme={"system"}
SELECT
    date,
    category,
    value,
    RANK() OVER (PARTITION BY category ORDER BY value DESC) as rank
FROM metrics
QUALIFY rank <= 3;  -- Keep only top 3 values per category
```

### SAMPLE

The SAMPLE clause allows you to query a random sample of rows.

```sql theme={"system"}
-- Sample 10% of rows
SELECT *
FROM large_table
SAMPLE 0.1;

-- Sample with offset
SELECT *
FROM large_table
SAMPLE 0.1 OFFSET 0.5;
```

### ARRAY JOIN

The ARRAY JOIN clause allows you to join with array or nested data structures.

```sql theme={"system"}
SELECT
    user_id,
    tags.name as tag_name,
    tags.value as tag_value
FROM users
ARRAY JOIN tags;
```

### FORMAT

The FORMAT clause specifies the output format of the query results.

```sql theme={"system"}
-- Output as JSON
SELECT *
FROM table_name
FORMAT JSON;

-- Output as CSV
SELECT *
FROM table_name
FORMAT CSV;
```

### INTO OUTFILE

The INTO OUTFILE clause writes query results to a file.

```sql theme={"system"}
SELECT *
FROM table_name
INTO OUTFILE 'path/to/file.csv'
FORMAT CSV;

-- With compression
SELECT *
FROM table_name
INTO OUTFILE 'path/to/file.gz'
COMPRESSION 'gzip'
LEVEL 1
FORMAT CSV;
```

### SETTINGS

The SETTINGS clause allows you to specify query-specific settings.

```sql theme={"system"}
SELECT *
FROM table_name
SETTINGS
    max_execution_time=10,
```
