SQL から LINQ への変換、パート 9 : 完全外部結合 (Bill Horst)

ここでは、このシリーズの以前の投稿 (英語) をお読みになっていることを前提としています。前提とする状況はパート 8 と同じで、前回の続きとなる、完全外部結合の変換についてお話します。これが理想的な方法でないことはわかっていますので、将来の VB のリリースで完全外部結合のサポートを強化して欲しいとお考えの場合は、製品フィードバック サイトからご提案をお送りください。

 

完全外部結合は、基本的には、左外部結合と右外部結合の結果の結合に似ています。レコードは共通のフィールドに基づいて結合され、一致するものがないすべてのレコードも、"左" または "右" のテーブルに表示されます。

 

SQL

SELECT Contact.ContactName, Shipment.OrderDate

FROM CustomerTable Contact

FULL OUTER JOIN OrderTable Shipment

   ON Contact.CustomerID = Shipment.CustomerID

 

 

前回の投稿と同じデータを使用するこのクエリでは、次のような結果が得られます。

 

Results:

ContactName OrderDate

John Doe NULL

Bill Horst 3/25/1982

Bill Horst 3/13/2005

Jane Doe 9/29/2007

NULL 1/31/2008

 

左結合および右結合と同様に、完全外部結合は LINQ で直接にはサポートされませんが、同じ結果を得るようにクエリを記述することができます。現在のところ、これを行う最も簡単な方法は、3 つのサブクエリを連結することです。

 

最初のクエリでは、"右" テーブルに null 値がある結果が得られます。

 

VB

From Contact In CustomerTable _

Group Join Shipment In OrderTable _

  On Contact.CustomerID Equals Shipment.CustomerID _

  Into HaveMatch = Any() _

Where Not HaveMatch _

Select Contact.ContactName, OrderDate = NothingDate

 

Results:

{ContactName = "John Doe", OrderDate = Nothing}

 

 

2 番目のクエリでは、内部結合の結果が得られます。

 

VB

From Contact In CustomerTable _

Join Shipment In OrderTable _

  On Contact.CustomerID Equals Shipment.CustomerID _

Select Contact.ContactName, Shipment.OrderDate

 

Results:

{ContactName = "Bill Horst", OrderDate = #3/25/1982#}

{ContactName = "Bill Horst", OrderDate = #3/13/2005#}

{ContactName = "Jane Doe", OrderDate = #9/29/2007#}

 

 

3 番目のクエリでは、"左" テーブルに null 値がある結果が得られます。

 

VB

From Shipment In OrderTable _

Group Join Contact In CustomerTable _

  On Contact.CustomerID Equals Shipment.CustomerID _

  Into HaveMatch = Any() _

Where Not HaveMatch _

Select ContactName = NothingString, Shipment.OrderDate

 

Results:

{ContactName = Nothing, OrderDate = #1/31/2008#}

 

 

これらの結果を結合して、完全外部結合を得ることができます。

 

VB

(From Contact In CustomerTable _

 Group Join Shipment In OrderTable _

   On Contact.CustomerID Equals Shipment.CustomerID _

   Into HaveMatch = Any() _

 Where Not HaveMatch _

 Select Contact.ContactName, OrderDate = NothingDate) _

 .Concat(From Contact In CustomerTable _

         Join Shipment In OrderTable _

           On Contact.CustomerID Equals Shipment.CustomerID _

         Select Contact.ContactName, Shipment.OrderDate) _

         .Concat(From Shipment In OrderTable _

                 Group Join Contact In CustomerTable _

                   On Contact.CustomerID Equals Shipment.CustomerID _

                   Into HaveMatch = Any() _

                 Where Not HaveMatch _

                 Select ContactName = NothingString, Shipment.OrderDate)

 

Results:

{ContactName = "John Doe", OrderDate = Nothing}

{ContactName = "Bill Horst", OrderDate = #3/25/1982#}

{ContactName = "Bill Horst", OrderDate = #3/13/2005#}

{ContactName = "Jane Doe", OrderDate = #9/29/2007#}

{ContactName = Nothing, OrderDate = #1/31/2008#}

 

 

この説明が少しでもお役に立てればと願っています。前に書いたように、これが完全外部結合の理想的な実装方法とは考えていません。将来の VB のリリースで、もっと単純な構文で完全外部結合がサポートされることをお望みの場合は、ぜひ製品フィードバック サイトからご提案をお送りください。

 

また、私は LINQ についての投稿の種もあまり持ち合わせていません。別のトピックについての投稿をご希望の方は、ぜひご提案ください。

 

-      VB IDE テスト、Bill Horst

VB チーム

投稿 : 2008 年 2 月 12 日 8:47 AM

分類 : LINQ/VB9VB2008Bill HorstConverting SQL to LINQ

VB チームの Web ログ - https://blogs.msdn.com/vbteam/archive/2008/02/12/converting-sql-to-linq-part-9-full-outer-join-bill-horst.aspx (英語) より