適用対象:SQL Server
Azure SQL Database
Azure SQL Managed Instance
Azure Synapse Analytics
Analytics Platform System (PDW)
Microsoft Fabric のウェアハウス
Microsoft Fabric の SQL データベース
SELECT...INTO ステートメントは、既定のファイル グループに新しいテーブルを作成し、クエリから結果の行を挿入します。 完全な SELECT 構文については、「 SELECT」を参照してください。
Syntax
[ INTO new_table ]
[ ON filegroup ]
Arguments
new_table
選択リストの列とデータ ソースから選択した行に基づいて、作成する新しいテーブルの名前を指定します。
new_table の形式は、選択リスト内の式を評価することによって決まります。
new_table 内の列は、選択リストの指定順に作成されます。
new_table 内の各列の名前、データ型、NULL 値の許容属性、値は、選択リスト内の対応する式と同じになります。 列の IDENTITY プロパティは、「解説」セクションの「ID 列の操作」で定義されている条件を除いて転送されます。
同じ SQL Server インスタンスの別のデータベースにテーブルを作成するには、new_table を database.schema.table_name の形式で完全修飾名として指定します。
リモート サーバーに new_table を作成することはできません。 ただし、リモート データ ソースから new_table を設定することはできます。 リモート ソース テーブルからnew_tableを作成するには、フォーム linked_serverで 4 部構成の名前を使用してソース テーブルを指定します。カタログ。スキーマ。SELECT ステートメントのFROM句内のオブジェクト。 または、FROM句で OPENQUERY 関数または OPENDATASOURCE 関数を使用して、リモート データ ソースを指定することもできます。
filegroup
新しいテーブルを作成するファイル グループの名前を指定します。 ファイル グループがデータベースに存在している必要があります。または、SQL Server エンジンからエラーが返されます。
適用対象: SQL Server 2016 (13.x) SP2 以降。
データ型
FILESTREAM 属性は新しいテーブルに転送されません。 FILESTREAM BLOB がコピーされ、varbinary(max) BLOB として新しいテーブルに格納されます。 FILESTREAM 属性がない場合、varbinary(max) データ型は 2 GB までに制限されます。 FILESTREAM BLOB がこの値を超えると、エラー 7119 が発生し、ステートメントが停止します。
新しいテーブルに既存の ID 列を選択すると、次のいずれかの条件が当てはまる場合を除き、新しい列は IDENTITY プロパティを継承します。
-
SELECTステートメントには結合が含まれています。 - 複数の
SELECTステートメントは、UNIONを使用して結合されます。 - ID 列が選択リストに 2 回以上指定されている。
- ID 列が式の一部である。
- ID 列がリモート データ ソースから取得されている。
これらの条件のいずれかが true の場合、IDENTITY プロパティを継承する代わりにNOT NULL列が作成されます。 新しいテーブルに ID 列が必要だが、そのような列が使用できない場合、またはソース ID 列とは異なるシード値または増分値が必要な場合は、 IDENTITY 関数を使用して選択リストの列を定義します。 「例」セクションの「 IDENTITY 関数を使用した ID 列の作成」を参照してください。
Remarks
SELECT...INTO ステートメントは、新しいテーブルが作成され、行が挿入されるという 2 つの部分で動作します。 この 2 段階のプロセスでは、挿入が失敗した場合、操作はすべての挿入をロールバックしますが、新しい (空の) テーブルは残ります。 操作が全体として成功または失敗した場合、明示的なトランザクションを使用します。
Microsoft Fabric のウェアハウスでは、ファイル グループはサポートされていません。 この記事でのファイル グループに関する記述と例は、Microsoft Fabric のウェアハウスには適用されません。
制限事項
テーブル変数またはテーブル値パラメーターを新しいテーブルとして指定することはできません。
ソース テーブルがパーティション分割されている場合でも、 SELECT...INTO を使用してパーティション テーブルを作成することはできません。
SELECT...INTO では、ソース テーブルのパーティション構成は使用されません。 代わりに、新しいテーブルが既定のファイル グループに作成されます。 パーティション テーブルに行を挿入するには、まずパーティション テーブルを作成してから INSERT INTO...SELECT...FROM ステートメントを使用する必要があります。
ソース テーブルで定義されているインデックス、制約、トリガーは新しいテーブルに転送されず、 SELECT...INTO ステートメントで指定することもできません。 これらのオブジェクトが必要な場合は、 SELECT...INTO ステートメントの実行後に作成できます。
ORDER BY句を指定しても、指定した順序で行が挿入されるとは限りません。
選択リストにスパース列を含めると、スパース列プロパティは新しいテーブルの列に転送されません。 新しいテーブルでこのプロパティが必要な場合は、 SELECT...INTO ステートメントの実行後に列定義を変更して、このプロパティを含めます。
選択リストに計算列を含めると、新しいテーブルの対応する列は計算列ではありません。 新しい列の値は、SELECT...INTO が実行された時点の計算値になります。
ログの動作
SELECT...INTO のログ記録量は、データベースに対して有効な復旧モデルによって異なります。 単純復旧モデルまたは一括ログ復旧モデルでは、一括操作は最小限しかログに記録されません。 ログ記録を最小限に抑えた場合、 SELECT...INTO ステートメントは、テーブルを作成し、テーブルに INSERT ステートメントを設定するよりも効率的です。 詳細については、 トランザクション ログ に関する記事を参照してください。
SELECT...INTO ユーザー定義関数 (UDF) を含むステートメントは、完全なログが記録される操作です。
SELECT...INTO ステートメントで使用されるユーザー定義関数がデータ アクセス操作を実行しない場合は、ユーザー定義関数のSCHEMABINDING句を指定できます。 この句は、ユーザー定義関数の派生 UserDataAccess プロパティを 0に設定します。 この変更後、 SELECT...INTO ステートメントは最小限に記録されます。
SELECT...INTO ステートメントで、このプロパティが 1 に設定されているユーザー定義関数が少なくとも 1 つ参照されている場合、操作は完全にログに記録されます。
Permissions
データベースの CREATE TABLE 権限と、テーブルを作成するスキーマの ALTER 権限が必要です。
Examples
A. 複数のソースの列を指定してテーブルを作成する
以下の例は、従業員関連および住所関連の様々なテーブルから7列を選択してAdventureWorks2025データベース内のテーブル dbo.EmployeeAddresses を作成します。
SELECT c.FirstName,
c.LastName,
e.JobTitle,
a.AddressLine1,
a.City,
sp.Name AS [State/Province],
a.PostalCode
INTO dbo.EmployeeAddresses
FROM Person.Person AS c
INNER JOIN HumanResources.Employee AS e
ON e.BusinessEntityID = c.BusinessEntityID
INNER JOIN Person.BusinessEntityAddress AS bea
ON e.BusinessEntityID = bea.BusinessEntityID
INNER JOIN Person.Address AS a
ON bea.AddressID = a.AddressID
INNER JOIN Person.StateProvince AS sp
ON sp.StateProvinceID = a.StateProvinceID;
B. 最小ログ記録を使用して行を挿入する
次の例では、テーブル dbo.NewProducts を作成し、Production.Product テーブルの行を挿入します。 この例では、AdventureWorks2025 データベースの復旧モデルが FULL に設定されていることを前提としています。 ログ記録を最小限に抑えるために、AdventureWorks2025 データベースの復旧モデルは、行を挿入する前にBULK_LOGGEDに設定され、SELECT...INTO ステートメントの後にFULLにリセットされます。 このプロセスにより、 SELECT...INTO ステートメントでトランザクション ログ内の最小領域が使用され、効率的に実行されます。
ALTER DATABASE AdventureWorks2025
SET RECOVERY BULK_LOGGED;
GO
SELECT *
INTO dbo.NewProducts
FROM Production.Product
WHERE ListPrice > $25
AND ListPrice < $100;
GO
ALTER DATABASE AdventureWorks2025
SET RECOVERY FULL;
GO
C. ID 関数を使用して ID 列を作成する
次の例では、 IDENTITY 関数を使用して、AdventureWorks2025 データベースの新しいテーブル Person.USAddress に ID 列を作成します。 テーブルを定義する SELECT ステートメントに結合が含まれているため、この手順が必要です。これにより、 IDENTITY プロパティが新しいテーブルに転送されなくなります。
IDENTITY関数で指定されたシード値とインクリメント値は、ソース テーブル Person.AddressのAddressID列の値とは異なります。
-- Determine the IDENTITY status of the source column AddressID.
SELECT OBJECT_NAME(object_id) AS TableName,
name AS column_name,
is_identity,
seed_value,
increment_value
FROM sys.identity_columns
WHERE name = 'AddressID';
-- Create a new table with columns from the existing table Person.Address.
-- A new IDENTITY column is created by using the IDENTITY function.
SELECT IDENTITY (INT, 100, 5) AS AddressID,
a.AddressLine1,
a.City,
b.Name AS State,
a.PostalCode
INTO Person.USAddress
FROM Person.Address AS a
INNER JOIN Person.StateProvince AS b
ON a.StateProvinceID = b.StateProvinceID
WHERE b.CountryRegionCode = N'US';
-- Verify the IDENTITY status of the AddressID columns in both tables.
SELECT OBJECT_NAME(object_id) AS TableName,
name AS column_name,
is_identity,
seed_value,
increment_value
FROM sys.identity_columns
WHERE name = 'AddressID';
D. リモート データ ソースの列を指定してテーブルを作成する
次の例は、ローカル サーバーで新しいテーブルをリモート データ ソースから作成するための 3 つの方法を示しています。 最初にリモート データ ソースへのリンクを作成した後、 リンク サーバー名MyLinkServer,は、最初の SELECT...INTO ステートメントのFROM句と、2 番目の SELECT...INTO ステートメントのOPENQUERY関数で指定されます。 3 番目の SELECT...INTO ステートメントでは、リンク サーバー名を使用する代わりにリモート データ ソースを直接指定する OPENDATASOURCE 関数を使用します。
USE master;
GO
-- Create a link to the remote data source.
-- Specify a valid server name for @datasrc as 'server_name'
-- or 'server_name\instance_name'.
EXECUTE sp_addlinkedserver
@server = N'MyLinkServer',
@srvproduct = N' ',
@provider = N'SQLNCLI',
@datasrc = N'server_name',
@catalog = N'AdventureWorks2025';
USE AdventureWorks2025;
GO
-- Specify the remote data source in the FROM clause using a four-part name
-- in the form linked_server.catalog.schema.object.
SELECT DepartmentID,
Name,
GroupName,
ModifiedDate
INTO dbo.Departments
FROM MyLinkServer.AdventureWorks2025.HumanResources.Department;
GO
-- Use the OPENQUERY function to access the remote data source.
SELECT DepartmentID,
Name,
GroupName,
ModifiedDate
INTO dbo.DepartmentsUsingOpenQuery
FROM OPENQUERY (
MyLinkServer,
'SELECT * FROM AdventureWorks2025.HumanResources.Department'
);
GO
-- Use the OPENDATASOURCE function to specify the remote data source.
-- Specify a valid server name for Data Source using the format
-- server_name or server_name\instance_name.
SELECT DepartmentID,
Name,
GroupName,
ModifiedDate
INTO dbo.DepartmentsUsingOpenDataSource
FROM OPENDATASOURCE (
'SQLNCLI',
'Data Source = server_name;Integrated Security = SSPI'
).AdventureWorks2025.HumanResources.Department;
E. PolyBase で作成された外部テーブルをインポートする
この例では、永続的ストレージ用に Hadoop または Azure Storage から SQL Server にデータをインポートします。 次に、 SELECT INTO を使用して、SQL Server の永続ストレージ用に外部テーブルによって参照されるデータをインポートします。 最後に、その場でリレーショナル テーブルを作成し、テーブルに列ストア インデックスを作成します。
適用対象: SQL Server。
-- Import data for car drivers into SQL Server to do more in-depth analysis.
SELECT DISTINCT Insured_Customers.FirstName,
Insured_Customers.LastName,
Insured_Customers.YearlyIncome,
Insured_Customers.MaritalStatus
INTO Fast_Customers
FROM Insured_Customers
INNER JOIN (SELECT *
FROM CarSensor_Data
WHERE Speed > 35) AS SensorD
ON Insured_Customers.CustomerKey = SensorD.CustomerKey
ORDER BY YearlyIncome;
F. テーブル間でデータをコピーし、指定したファイル グループに新しいテーブルを作成する
次の例は、新しいテーブルを別のテーブルのコピーとして作成し、ユーザーの既定のファイル グループとは異なる、指定したファイル グループに読み込む方法を示しています。
適用対象: SQL Server 2016 (13.x) SP2 以降。
ALTER DATABASE [AdventureWorksDW2022]
ADD FILEGROUP FG2;
GO
ALTER DATABASE [AdventureWorksDW2022]
ADD FILE (
NAME = 'FG2_Data',
FILENAME = '/var/opt/mssql/data/AdventureWorksDW2022_Data1.mdf'
) TO FILEGROUP FG2;
GO
SELECT *
INTO [dbo].[FactResellerSalesXL] ON FG2
FROM [dbo].[FactResellerSales];