---
schema_version: "1"
id: f48fa913679167d44c2d6c117af6d23dd3510e1ac5bedef7d73d578953e172a0
title: Reading External Data in SQL
collection: developer
version: current
locale: en-us
portal_url: https://docs.salesforce.com/developer/current/en-us/data-cloud/data-cloud-query-guide/references/data-cloud-sql-reference/external/external-syntax.md
canonical_url: https://developer.salesforce.com/docs/data/data-cloud-query-guide/references/dc-sql-reference/external-syntax.html
source_site: developer.salesforce.com
content_type: documentation
content_hash: 8aab0c9e9a81e46752587865641fba9b9998e058f646c7fa7ad31bddeacab304
products:
  - Data 360 Query Guide
  - Data 360 Developer Documentation
---
# Reading External Data in SQL

**Applies to:** ❌ Data 360 SQL ✅ Tableau Hyper API

Data 360 SQL provides three options for using external data in SQL.

- Copied into a table with the [COPY FROM](https://developer.salesforce.com/docs/data/data-cloud-query-guide/references/tableau-sql-commands/copy-from.md) SQL command.

- Read directly in a SQL query by using the set returning function [external](https://developer.salesforce.com/docs/data/data-cloud-query-guide/references/set-returning-func/external.md).

- Exposed as if it was a table using the [CREATE EXTERNAL TABLE](https://developer.salesforce.com/docs/data/data-cloud-query-guide/references/tableau-sql-commands/create-external-table.md) SQL command. It can then subsequently be queried by using the name of the external table.

Usage examples of the individual alternatives can be found in the documentation of the respective statements. The choice among these ways to access external data depends on the use case.

## `COPY` vs. `INSERT` \+ `external`

`COPY` creates a copy of the data in a table. It’s functionally equivalent to an [INSERT](https://developer.salesforce.com/docs/data/data-cloud-query-guide/references/tableau-sql-commands/insert.md) command that reads from the `external` function. For example, these two statements have the same effect, assuming that `'products.parquet'` has the same columns as the existing table `products`.

```sql
COPY products FROM 'products.parquet';

INSERT INTO products (SELECT * FROM external('products.parquet'))
```

The `COPY` statement automatically selects only the columns that are in the target table. The insert statement names the columns to insert explicitly. For formats that don’t carry schema information, such as CSV, `COPY` assumes that the file has the table’s schema, while `external` requires the schema to be given explicitly.

In general, using `INSERT` with `external` is more flexible because it can transform and filter the data before it’s inserted into the table. For example, this query inserts products with a price greater than 100 and transforms the product name to upper case.

```sql
INSERT INTO products (
    SELECT upper(name), price
    FROM external('products.parquet')
    WHERE price > 100)
```

`external` can also be used in `CREATE TABLE AS` statements to create and fill a new table. For example, this example creates and fills a products table.

```sql
CREATE TABLE products AS (SELECT * FROM external('products.parquet'))
```

## Creating External Tables vs. Using Ad-hoc Queries

The set returning function `external` and the `CREATE TEMPORARY EXTERNAL TABLE` statement can be used to query external data without inserting it into a table.

With `external`, you can write a fully self-contained query that doesn’t rely on external tables being set up before. `CREATE TEMPORARY EXTERNAL TABLE` enables reading external data as if it was a table. As a result, SQL queries can operate on a table or on an external table without changing their syntax.

`CREATE TEMPORARY EXTERNAL TABLE` infers the schema of the source on creation. If the source file then gets replaced by a file with a different schema, subsequent queries fail. In contrast, `external` re-infers the schema whenever the query containing it’s executed.
