SQL ServerJOIN句
- 12-09-2022
- Toanngo92
- 0 Comments
Mục lục
SQLServerでのJOINの紹介
JOINは、テーブル間の論理関係に基づいて2つ以上のテーブルからデータを取得するために使用されます。結合( JOIN )は通常、テーブル間の外部キー関係を指定します。これは、クエリで2つのテーブルがどのように関連しているかを次のように決定します。
- 結合に使用する各テーブルの列を指定します( JOIN )。一般的な結合( JOIN )は、あるテーブルの外部キーと別のテーブルの関連キーを指定します。
- 列の値を比較するために使用する=、<>などの論理演算子を指定します。
JOINは、 FROM句またはWHERE句で指定できます。
構文:
SELECT <ColumnName1>, <ColumnName2>, ... <ColumnNameN> FROM Table_Name1 AS alias_1 JOIN Table_Name2 AS alias_2 ON alias_1.<RelatedColumn> = alias_2.<RelatedColumn>
HumanResources.EmployeeテーブルとPerson.Personテーブルから従業員名、姓、役職のリストを取得するとします。 2つのテーブルの情報を取得するには、BusinessEntiyID列の外部キーの関連付けに従って2つのテーブルを結合する必要があります。例えば:
SELECT A.FirstName,A.LastName,B.JobTitle FROM Person.Person A JOIN HumanResources.Employee B ON A.BusinessEntityID = B.BusinessEntityID
この問題をさらに発展させるために、3つの概念的なJOINSタイプがあります。
- 内部結合
- 外部結合
- 自己結合
インナージョイン
内部結合は、2つのテーブルのレコードが、両方のテーブルの行が共通の列に基づいて一致する場合にのみ結合されるときに形成されます。
JOINとINNERJOINの違い:JOINは、あるテーブルのキーレコードが別のテーブルのキーレコードと等しいテーブルからすべての行を返します。 INNER JOINは、列が一致する限り、両方の結合テーブルからすべての行を選択します
構文:
SELECT <ColumnName1>,<ColumnName2> ... <ColumnNameN> FROM Table_A AS Table_Alias_A INNER JOIN Table_B AS Table_Alias_B ON Table_Alias_A.<RelatedColumn> = Table_Alias_B.<RelatedColumn>
例えば:
SELECT A.FirstName, A.LastName, B.JobTitle FROM Person.Person A INNER JOIN HumanResources.Employee B ON A.BusinessEntityID = b.BusinessEntityID
アウタージョイン
外部結合は、 FROM句で指定されたテーブルの少なくとも1つからすべての行を返す結合ステートメントです。ただし、これらの行がSELECTステートメントのWHEREまたはHAVING条件を満たす場合に限ります。一般的に使用される2つの外部結合タイプは次のとおりです。
- 左アウタージョイン
- 右アウタージョイン
左アウタージョイン
左側の外部結合は、左側のテーブルからすべてのレコードを返し、右側の一致したレコードのみを返します。
構文:
SELECT <ColumnList> FROM Table_A AS ALIAS_A LEFT OUTER JOIN Table_B AS ALIAS_B ON ALIAS_A.<RelatedColumn> = ALIAS_B.<RelatedColumn>
Sales.Customersテーブルからすべての顧客IDを取得し、出荷日、期日などの注文情報を取得したいとします。注文をしなかった顧客も取得しますが、レコード数が非常に多いため、事前に制限を注文します。 2019年、これを行うには、次のようにLEFTOUTERJOINを実行します。
SELECT A.CustomerID, B.DueDate, B.ShipDAte FROM Sales.Customer A LEFT OUTER JOIN Sales.SalesOrderHeader B ON A.CustomerID = B.CustomerID AND YEAR(B.DueDate) < 2019
上記のコードでは、左側の外部結合は、 Sales.CustomerテーブルとSales.SalesOrderHeaderテーブルの間の構造です。テーブルは、顧客ID列に基づいて結合されます。この状況では、左側のテーブルのすべてのレコードがSales.Customerであり、右側のテーブルの一致するレコードのみがSales.SalesOrderHeaderです。右側のテーブルのデータが一致しない場合でも、左側のテーブルが取得され、テーブルはデータの右側はnullを返します。
右アウタージョイン
右外部結合は、最初のテーブルに一致があるかどうかに関係なく、結合の右テーブルからすべてのレコードを取得します。
SELECT <ColumnList> FROM Left_Table_Name AS Alias_A RIGHT OUTER JOIN Table_B as ALIAS_B ON Alias_A.<RelatedColumn> = Allias_B.<RelatedColumn>
たとえば、次のように、SalesOrderDetailテーブル(未販売の製品)のデータと一致しない製品レコードが存在する場合でも、productテーブルからすべての製品名を取得し、SalesOrderDetailテーブルからすべての対応する注文を取得するとします。
SELECT P.Name,S.SalesOrderID FROM Sales.SalesOrderDetail S RIGHT OUTER JOIN Production.Product P ON P.ProductID = S.ProductID
自己参加
自己結合結合は、同じテーブル上のレコード間の関係を示すために使用されます。それ自体に結合されるテーブルは、自己結合と呼ばれます。
たとえば、自己結合を使用して、 Production.Productテーブルで同じ色の製品の詳細を取得するとします。
SELECT p1.ProductID, p1.Color, p1.Name, p2.Name FROM Production.Product p1 INNER JOIN Production.Product p2 ON p1.Color = p2.Color ORDER BY p1.ProductID
MERGE。ステートメント
MERGEステートメントを使用すると、単一のステートメントを使用して、ソーステーブルの特定の結合条件下で宛先テーブルを維持できます。
たとえば、必要な場合:
- 2つのソーステーブルと宛先テーブルからの顧客の姓と名を比較します
- 名と姓が一致する場合は、宛先テーブルの顧客情報を更新します
- ソーステーブルの姓と名が宛先テーブルに存在しない場合は、宛先テーブルに新しいレコードを追加します
- 姓と名がソーステーブルと一致しない場合は、宛先テーブルのレコードを削除します
MERGEステートメントは、単一のステートメントでタスクを完了します。 MERGEでは、OUTPUT句を使用して挿入、更新、または削除されたレコードを表示することもできます。
構文:
MERGE target_table USING source_table ON match_condition WHEN MATCHED THEN UPDATE SET col1 = vale [,Col2 = val2] WHEN [TARGET] NOT MATCHED THEN INSERT (Col1[,Col2...]) VALUES(Val1[,Val2...]) WHEN NOT MATCH BY SOURCE THEN DELETE [OUTPUT $action, inserted.Col1,Deleted.Col1,....];
説明:
- target_table:ここでデータが変更されるターゲットテーブル
- source_table:ソーステーブル。宛先テーブルで追加、更新、および削除できるレコードが含まれています
- match_conditions:結合条件(JOIN)および任意の比較演算子。
- MATCHED:target_tableレコードとsource_tableレコードがmatch_conditionに一致する場合にtrueを返します。
- NOT MATCHED:source_tableのレコードがtarget_tableに存在しない場合、trueを返します。
- SOURCE NOT MATCH:レコードがtarget_tableに存在するが、source_tableには存在しない場合に返されます。
- 出力:オプションの句を使用すると、target_Tableでテーマ化/削除/更新されたレコードを表示できます。
MERGEステートメントはセミコロン(;)で終わります。
例えば:
use AdventureWorks2019 go SET IDENTITY_INSERT [Person].[AddressType] ON MERGE INTO [Person].[AddressType] AS Target USING (VALUES (1,'Billing') , (2,'Home'),(3,'Headquarters'),(4,'Primary'),(5,'Shipping'),(6,'Archival'),(7,'Contact'),(8,'Alternative')) AS Source ([AddressTypeID],[Name]) ON (Target.[AddressTypeID] = Source.[AddressTypeID]) WHEN MATCHED AND (Target.[Name] <> Source.[Name]) THEN UPDATE SET [Name] = Source.[NAME] WHEN NOT MATCHED BY TARGET THEN INSERT ([AddressTypeID],[Name]) VALUES(Source.[AddressTypeID],Source.[Name]) WHEN NOT MATCHED BY SOURCE THEN DELETE OUTPUT $action, Inserted.[AddressTypeID], Inserted.Name, Deleted.[AddressTypeID], Deleted.Name;
Table Person.AddressTypeは宛先テーブルであり、サンプルデータはUSINGコマンドを介して挿入されます(VALUES(1、’Billing’)、(2、’Home’)、(3、’Headquarters’)、(4、’Primary’) 、(5、’Shipping’)、(6、’Archival’)、(7、’Contact’)、(8、’Alternative’))AS Sourceはソーステーブルであり、一致条件は両方のテーブルのAddressTypeID列です。 。ソースとターゲット。一致条件がfalseと評価された場合(一致していません)。新しいレコードが宛先テーブルに追加されます。一致条件がtrue(MATCHED)を返す場合、レコードはソーステーブルのデータに基づいて宛先テーブルに更新されます。
宛先テーブルのレコードがソーステーブルと一致しない場合(ソースによって一致しない)、それらは宛先テーブルから削除されます。最後のステートメントの役割は、追加/更新/削除された行を報告し、出力を表示することです。