Leer en inglés

Compartir a través de

查询文件夹和多个文件

在本文中,你将了解如何在 Azure Synapse Analytics 中使用无服务器 SQL 池编写查询。

无服务器 SQL 池支持使用通配符(类似于 Windows 中使用的通配符)读取多个文件或文件夹。 但是,由于允许使用多个通配符,因此需要更大的灵活性。

先决条件

第一步是创建可在其中执行查询的数据库。 然后通过对该数据库执行安装脚本来初始化这些对象。 此安装脚本将创建数据源、数据库范围的凭据以及在这些示例中使用的外部文件格式。

请使用文件夹 csv/taxi 来参考示例查询。 它包含 2016 年 7 月到 2018 年 6 月的 NYC Taxi - Yellow Taxi Trip Records 数据csv/taxi 中的文件采用以下格式按年份和月份命名:

yellow_tripdata_<year>-<month>.csv*

读取文件夹中的所有文件

以下示例从 csv/taxi 文件夹中读取所有 NYC Yellow Taxi 数据文件,然后返回每年乘客总数和搭乘总次数。 它还显示聚合函数的使用情况。

SELECT 
    YEAR(pickup_datetime) as [year],
    SUM(passenger_count) AS passengers_total,
    COUNT(*) AS [rides_total]
FROM OPENROWSET(
        BULK 'csv/taxi/*.csv',
        DATA_SOURCE = 'sqlondemanddemo',
        FORMAT = 'CSV', PARSER_VERSION = '2.0',
        FIRSTROW = 2
    )
    WITH (
        pickup_datetime DATETIME2 2, 
        passenger_count INT 4
    ) AS nyc
GROUP BY
    YEAR(pickup_datetime)
ORDER BY
    YEAR(pickup_datetime);

Nota

使用单个 OPENROWSET 访问的所有文件必须具有相同的结构(列数及其数据类型)。

读取文件夹中的文件子集

以下示例使用通配符读取 csv/taxi 文件夹中的 2017 NYC Yellow Taxi 数据文件,并返回每个付款类型的总费用金额。

SELECT 
    payment_type,  
    SUM(fare_amount) AS fare_total
FROM OPENROWSET(
        BULK 'csv/taxi/yellow_tripdata_2017-*.csv',
        DATA_SOURCE = 'sqlondemanddemo',
        FORMAT = 'CSV', PARSER_VERSION = '2.0',
        FIRSTROW = 2
    )
    WITH (
        payment_type INT 10,
        fare_amount FLOAT 11
    ) AS nyc
GROUP BY payment_type
ORDER BY payment_type;

Nota

使用单个 OPENROWSET 访问的所有文件必须具有相同的结构(列数及其数据类型)。

使用多个文件路径读取文件夹中的文件子集

以下示例使用两个文件路径读取 csv/taxi 文件夹中的 2017 NYC Yellow Taxi 数据文件。 首先,使用包含一月份数据的文件的完整路径;其次,使用通配符读取包含十月、十一月和十二月数据的文件。 对于每个路径,将返回每个付款类型的总费用金额。

SELECT 
    payment_type,  
    SUM(fare_amount) AS fare_total
FROM OPENROWSET(
        BULK (
            'csv/taxi/yellow_tripdata_2017-01.csv',
            'csv/taxi/yellow_tripdata_2017-1*.csv'
        ),
        DATA_SOURCE = 'sqlondemanddemo',
        FORMAT = 'CSV', PARSER_VERSION = '2.0',
        FIRSTROW = 2
    )
    WITH (
        payment_type INT 10,
        fare_amount FLOAT 11
    ) AS nyc
GROUP BY payment_type
ORDER BY payment_type;

Nota

使用单个 OPENROWSET 访问的所有文件必须具有相同的结构(列数及其数据类型)。

读取文件夹

OPENROWSET 提供的路径也可以是指向文件夹的路径。 以下部分包含这些查询类型。

读取特定文件夹中的所有文件

可以使用文件级别通配符读取文件夹中的所有文件,如读取文件夹中所有文件所示。 但有一种方法可以查询文件夹并使用该文件夹中的所有文件。

如果 OPENROWSET 中提供的路径指向文件夹,则该文件夹中的所有文件都将用作查询的源。 以下查询将读取 csv/taxi 文件夹中的所有文件。

Nota

请注意查询中路径的末尾是否存在 /。 它表示文件夹。 如果省略了 /,则查询将改为以名为 taxi 的文件作为目标

SELECT
    YEAR(pickup_datetime) as [year],
    SUM(passenger_count) AS passengers_total,
    COUNT(*) AS [rides_total]
FROM OPENROWSET(
        BULK 'csv/taxi/',
        DATA_SOURCE = 'sqlondemanddemo',
        FORMAT = 'CSV', PARSER_VERSION = '2.0',
        FIRSTROW = 2
    )
    WITH (
        vendor_id VARCHAR(100) COLLATE Latin1_General_BIN2, 
        pickup_datetime DATETIME2, 
        dropoff_datetime DATETIME2,
        passenger_count INT,
        trip_distance FLOAT,
        rate_code INT,
        store_and_fwd_flag VARCHAR(100) COLLATE Latin1_General_BIN2,
        pickup_location_id INT,
        dropoff_location_id INT,
        payment_type INT,
        fare_amount FLOAT,
        extra FLOAT,
        mta_tax FLOAT,
        tip_amount FLOAT,
        tolls_amount FLOAT,
        improvement_surcharge FLOAT,
        total_amount FLOAT
    ) AS nyc
GROUP BY
    YEAR(pickup_datetime)
ORDER BY
    YEAR(pickup_datetime);

Nota

使用单个 OPENROWSET 访问的所有文件必须具有相同的结构(列数及其数据类型)。

读取多个文件夹中的所有文件

可以通过使用通配符从多个文件夹读取文件。 下面的查询读取 csv 文件夹中所有以 t 开头并以 i 结尾的文件夹中的所有文件。

Nota

请注意查询中路径的末尾是否存在 /。 它表示文件夹。 如果省略 /,则查询将改为以名为 t*i 的文件作为目标

SELECT
    YEAR(pickup_datetime) as [year],
    SUM(passenger_count) AS passengers_total,
    COUNT(*) AS [rides_total]
FROM OPENROWSET(
        BULK 'csv/t*i/', 
        DATA_SOURCE = 'sqlondemanddemo',
        FORMAT = 'CSV', PARSER_VERSION = '2.0',
        FIRSTROW = 2
    )
    WITH (
        vendor_id VARCHAR(100) COLLATE Latin1_General_BIN2, 
        pickup_datetime DATETIME2, 
        dropoff_datetime DATETIME2,
        passenger_count INT,
        trip_distance FLOAT,
        rate_code INT,
        store_and_fwd_flag VARCHAR(100) COLLATE Latin1_General_BIN2,
        pickup_location_id INT,
        dropoff_location_id INT,
        payment_type INT,
        fare_amount FLOAT,
        extra FLOAT,
        mta_tax FLOAT,
        tip_amount FLOAT,
        tolls_amount FLOAT,
        improvement_surcharge FLOAT,
        total_amount FLOAT
    ) AS nyc
GROUP BY
    YEAR(pickup_datetime)
ORDER BY
    YEAR(pickup_datetime);

Nota

使用单个 OPENROWSET 访问的所有文件必须具有相同的结构(列数及其数据类型)。

由于只有一个文件夹与条件匹配,因此查询结果与读取文件夹中的所有文件的相同。

以递归方式遍历文件夹

如果在路径末尾指定 /**,则无服务器 SQL 池可以递归方式遍历文件夹。 以下查询读取位于 csv/taxi 文件夹中的所有文件夹和子文件夹中的所有文件。

SELECT
    YEAR(pickup_datetime) as [year],
    SUM(passenger_count) AS passengers_total,
    COUNT(*) AS [rides_total]
FROM OPENROWSET(
        BULK 'csv/taxi/**', 
        DATA_SOURCE = 'sqlondemanddemo',
        FORMAT = 'CSV', PARSER_VERSION = '2.0',
        FIRSTROW = 2
    )
    WITH (
        vendor_id VARCHAR(100) COLLATE Latin1_General_BIN2, 
        pickup_datetime DATETIME2, 
        dropoff_datetime DATETIME2,
        passenger_count INT,
        trip_distance FLOAT,
        rate_code INT,
        store_and_fwd_flag VARCHAR(100) COLLATE Latin1_General_BIN2,
        pickup_location_id INT,
        dropoff_location_id INT,
        payment_type INT,
        fare_amount FLOAT,
        extra FLOAT,
        mta_tax FLOAT,
        tip_amount FLOAT,
        tolls_amount FLOAT,
        improvement_surcharge FLOAT,
        total_amount FLOAT
    ) AS nyc
GROUP BY
    YEAR(pickup_datetime)
ORDER BY
    YEAR(pickup_datetime);

Nota

使用单个 OPENROWSET 访问的所有文件必须具有相同的结构(列数及其数据类型)。

使用多个通配符

可以在不同的路径级别使用多个通配符。 例如,可以将之前的某个查询扩充为读取所有文件夹中名称以 t 开头并以 i 结尾且仅包含 2017 年数据的文件。

Nota

请注意查询中路径的末尾是否存在 /。 它表示文件夹。 如果省略 /,则查询将改为以名为 t*i 的文件作为目标。 每个查询最多有 10 个通配符。

SELECT
    YEAR(pickup_datetime) as [year],
    SUM(passenger_count) AS passengers_total,
    COUNT(*) AS [rides_total]
FROM OPENROWSET(
        BULK 'csv/t*i/yellow_tripdata_2017-*.csv',
        DATA_SOURCE = 'sqlondemanddemo',
        FORMAT = 'CSV', PARSER_VERSION = '2.0',
        FIRSTROW = 2
    )
    WITH (
        vendor_id VARCHAR(100) COLLATE Latin1_General_BIN2, 
        pickup_datetime DATETIME2, 
        dropoff_datetime DATETIME2,
        passenger_count INT,
        trip_distance FLOAT,
        rate_code INT,
        store_and_fwd_flag VARCHAR(100) COLLATE Latin1_General_BIN2,
        pickup_location_id INT,
        dropoff_location_id INT,
        payment_type INT,
        fare_amount FLOAT,
        extra FLOAT,
        mta_tax FLOAT,
        tip_amount FLOAT,
        tolls_amount FLOAT,
        improvement_surcharge FLOAT,
        total_amount FLOAT
    ) AS nyc
GROUP BY
    YEAR(pickup_datetime)
ORDER BY
    YEAR(pickup_datetime);

Nota

使用单个 OPENROWSET 访问的所有文件必须具有相同的结构(列数及其数据类型)。

由于只有一个文件夹与条件匹配,因此查询结果与读取文件夹中文件的子集读取特定文件夹中的所有文件的相同。 有关更复杂的通配符使用方案,请参阅查询 Parquet 文件

后续步骤