适用于:✅ Microsoft Fabric 中的仓库
Transact-SQL 语言提供了一些选项,可用于将数据从湖屋和仓库中的现有表大规模地加载到仓库中的新表中。 如果需要创建包含聚合数据的表的新版本、包含行子集的表版本,或者由于复杂查询而创建表,这些选项非常方便。 让我们举例说明。
使用查询结果创建新表
通过 Microsoft Fabric 中的仓库,可以使用以下 T-SQL 语句轻松基于 T-SQL 查询的结果创建新表:
-
CREATE TABLE AS SELECT(CTAS) 语句,允许你根据语句的SELECT输出在仓库中创建新表。 -
SELECT INTO查询子句,用于从任何表源中选择结果,并将结果重定向到新表中。 这是 T-SQL 语言的标准功能。
这两个语句类似,因此以下示例侧重于 CTAS 语句。
CTAS 语句将数据导入操作并行运行到新表中,从而大大提高了在工作区中进行数据转换和创建新表的效率。
可以将以下选项应用于 CTAS 语句中的 SELECT 部分:
- 读取仓库表,例如临时表。
- 在 Lakehouse 的 SQL 分析终结点中使用自动生成的表读取 Lakehouse Delta Lake 文件夹。
- 使用
OPENROWSET函数直接从 Azure Data Lake 或 Azure Blob 存储读取 CSV、Parquet 或 JSONL 文件。
Note
本文中的示例使用必应中的新冠肺炎示例数据集。 若要加载示例数据集,请按照使用 COPY 语句将数据引入仓库中的步骤操作,将示例数据创建到仓库中。
从仓库表创建表
第一个示例演示如何创建一个新表,该表是现有 dbo.bing_covid19_data_2023 表的副本,但仅筛选到 2023 年的数据:
CREATE TABLE dbo.bing_covid19_data_2023
AS
SELECT *
FROM dbo.bing_covid19_data
WHERE DATEPART(YEAR, updated) = '2023';
还可创建具有新的 year、month 和 dayofmonth 列的新表,其中包含从源表中的 updated 列获取的值。 如果尝试按年份直观显示感染数据,或者查看观察到最多新冠肺炎病例的月份,这非常有用:
CREATE TABLE dbo.bing_covid19_data_with_year_month_day
AS
SELECT DATEPART(YEAR, updated) AS [year],
DATEPART(MONTH, updated) AS [month],
DATEPART(DAY, updated) AS [dayofmonth],
*
FROM dbo.bing_covid19_data;
另一个示例是,你可以创建一个新表,来汇总每月观察到的病例数,而不考虑年份,以评估季节性如何影响在给定国家/地区的传播。 它使用在上一示例中创建的表,并将新的 month 列作为源:
CREATE TABLE dbo.infections_by_month
AS
SELECT country_region, [month],
SUM(CAST(confirmed as bigint)) AS confirmed_sum
FROM dbo.bing_covid19_data_with_year_month_day
GROUP BY country_region, [month];
根据这个新表,我们可以看到,美国在所有年份的 January 观察到了更多的确诊病例,其次是 December 和 October。
April 是总体病例数最少的月份:
SELECT * FROM dbo.infections_by_month
WHERE country_region = 'United States'
ORDER BY confirmed_sum DESC;
从 Delta Lake 文件夹创建表
如果 Delta Lake 文件夹存储在 lakehouse 的 /Tables 文件夹中,它们会在 OneLake 中自动表示为表。 在 bing_covid19_data_2023 lakehouse 中,以下代码从 Delta Lake 文件夹 /Tables/bing_covid19_delta_lake 创建了一个新表 :
CREATE TABLE dbo.bing_covid19_data_2023
AS
SELECT *
FROM MyLakehouse.dbo.bing_covid19_delta_lake
WHERE DATEPART(YEAR, updated) = '2023';
可以使用三部分名称表示法来引用 Delta Lake 文件夹,此名称指的是存储文件的 Lakehouse。 上一节中显示的所有示例都适用于 Delta Lake 文件夹。
从 CSV/Parquet/JSONL 文件创建表
还可以使用bing_covid19_data函数直接从外部文件创建新表,而不是从仓库OPENROWSET表读取数据:
CREATE TABLE dbo.bing_covid19_data_2022
AS
SELECT *
FROM OPENROWSET(BULK 'https://pandemicdatalake.blob.core.windows.net/public/curated/covid-19/bing_covid-19_data/latest/bing_covid-19_data.parquet') AS data
WHERE DATEPART(YEAR, updated) = '2022';
还可以通过转换外部 CSV 文件中的数据来创建新表:
CREATE TABLE dbo.bing_covid19_data_with_year_month_day
AS
SELECT DATEPART(YEAR, updated) AS [year],
DATEPART(MONTH, updated) AS [month],
DATEPART(DAY, updated) AS [dayofmonth],
*
FROM OPENROWSET(BULK 'https://pandemicdatalake.blob.core.windows.net/public/curated/covid-19/bing_covid-19_data/latest/bing_covid-19_data.csv') AS data;
另一个示例是,你可以创建一个新表,来汇总每月观察到的病例数,而不考虑年份,以评估季节性如何影响在给定国家/地区的传播。 它使用在上一示例中创建的表,并将新的 month 列作为源:
CREATE TABLE dbo.infections_by_month_2022
AS
SELECT country_region,
DATEPART(MONTH, updated) AS [month],
SUM(CAST(confirmed as bigint)) AS [confirmed_sum]
FROM OPENROWSET(BULK 'https://pandemicdatalake.blob.core.windows.net/public/curated/covid-19/bing_covid-19_data/latest/bing_covid-19_data.jsonl') AS data
WHERE DATEPART(YEAR, updated) = '2022'
GROUP BY country_region, DATEPART(MONTH, updated);
根据这个新表,我们可以看到,美国在所有年份的 January 观察到了更多的确诊病例,其次是 December 和 October。
April 是总体病例数最少的月份:
SELECT * FROM dbo.infections_by_month_2022
WHERE country_region = 'United States'
ORDER BY confirmed_sum DESC;
有关更多示例和语法参考,请参阅 CREATE TABLE AS SELECT (Transact-SQL)。
使用 T-SQL 查询将数据引入现有表
前面的示例基于查询结果创建新表。 若要复制示例,但对现有表,可以使用模式 INSERT ... SELECT 。
从数据仓库表引入数据
以下代码将仓库表中的新数据引入到现有表中:
INSERT INTO dbo.bing_covid19_data_2023
SELECT *
FROM dbo.bing_covid19_data
WHERE DATEPART(YEAR, updated) = '2023';
SELECT 语句的查询条件可以是任何有效的查询,只要生成的查询列类型与目标表上的列一致就行。 如果指定了列名,并且仅包含目标表中列的子集,则所有其他列都加载为 NULL。 有关详细信息,请参阅使用 INSERT INTO…SELECT,在最小程度的日志记录和并行度情况下批量导入数据。
从 Delta Lake 文件夹引入数据
如果 Delta Lake 文件夹存储在 Lakehouse 中的 /Tables 文件夹中,那么在 OneLake 中它们将被自动表示为表。
以下代码从 Lakehouse 中的 /Tables/bing_covid19_delta_lake Delta Lake 文件夹MyLakehouse*部分引入新数据
INSERT INTO dbo.bing_covid19_data_2023
SELECT *
FROM MyLakehouse.dbo.bing_covid19_delta_lake
WHERE DATEPART(YEAR, updated) = '2023';
从 CSV/Parquet/JSONL 文件引入数据
可以将函数 OPENROWSET 用作源,以便从存储中引入 Parquet、CSV 或 JSON 文件:
INSERT INTO dbo.bing_covid19_data_2023
SELECT *
FROM OPENROWSET(BULK 'https://pandemicdatalake.blob.core.windows.net/public/curated/covid-19/bing_covid-19_data/latest/bing_covid-19_data.parquet') AS data
WHERE DATEPART(YEAR, updated) = '2023';
可以使用通配符(例如 *.parquet)或针对分区目录(例如 /year=*/month=*)读取多个文件。 若要优化性能,请将 WHERE 子句中的筛选器应用于在查询执行过程中消除不必要的行和分区。
这些示例类似于在使用 COPY INTO 进行数据导入时使用的示例。 COPY INTO 命令更易于使用,尤其是对于直接的源到目标数据加载。 但是,如果需要转换源数据(例如转换数值或与其他表格联接),使用INSERT ... SELECT可以灵活地在数据引入期间执行这些转换。
从 OneLake 引入数据
可以将函数 OPENROWSET 用作源,以便从 Fabric OneLake 存储引入数据。 在以下示例中,用相应的工作区和 Lakehouse GUID 替换 {workspaceId} 和 {lakehouseId}。
INSERT INTO dbo.bing_covid19_data_2023
SELECT *
FROM OPENROWSET(BULK 'https://onelake.dfs.fabric.microsoft.com/{workspaceId}/{lakehouseId}/Files/year=*/month=*/*.parquet') AS data
WHERE data.filepath(1) = '2023'
此示例基于从 Azure Data Lake Storage 读取数据的上一个示例。 如果需要转换源数据,例如转换值、与其他表联接或读取特定分区,请使用此方法。 在这种情况下,使用 INSERT ... SELECT 可灵活地在数据引入期间应用转换。
从不同仓库和湖屋上的表引入数据
对于 CREATE TABLE AS SELECT 和 INSERT ... SELECT,SELECT 语句还可以通过使用跨仓库查询来引用与存储目标表的仓库不同的仓库中的表。 这可以通过使用由三部分构成的命名约定 [warehouse_or_lakehouse_name.][schema_name.]table_name 来实现。 例如,假设你具有以下工作区资产:
- 一个名为
cases_lakehouse的湖屋,其中包含最新的病例数据。 - 一个名为
reference_warehouse的仓库,其中包含用于引用数据的表。 - 一个名为
research_warehouse的仓库,在其中创建目标表。
可以创建一个新表,该表使用三部分命名来合并这些工作区资产上的表中的数据:
CREATE TABLE research_warehouse.dbo.cases_by_continent
AS
SELECT *
FROM cases_lakehouse.dbo.bing_covid19_data AS cases
INNER JOIN reference_warehouse.dbo.bing_covid19_data AS reference
ON cases.iso3 = reference.countrycode;
若要详细了解跨仓库查询,请参阅编写跨数据库 SQL 查询。
审核和监视 T-SQL 引入
通过 T-SQL 执行的CTAS和INSERT ... SELECT操作都会显示在仓库查询历史/活动中,并且可以与其他仓库操作一起进行监视。
数据引入选项
将数据引入仓库的其他方法包括: