ぼちぼち SQL Server 2017 の Graph 触ってます。
Graph processing with SQL Server and Azure SQL Database | Microsoft Docs
MATCH は、NOT 書けないようなので、代わりに NOT EXISTS を使うようです。
MATCH (SQL Graph) | Microsoft Docs
例:片思いの人を取得する。
A さんと D さんが片思いなデータを作ってみます。
create table [人] ( [名前] nvarchar(20) ) as node create table [好き] as edge insert into [人] values (N'Aさん'), (N'Bさん'), (N'Cさん'), (N'Dさん'), (N'Eさん') declare @id1 nvarchar(1000) = (select $node_id from [人] where [名前] = N'Aさん') declare @id2 nvarchar(1000) = (select $node_id from [人] where [名前] = N'Bさん') declare @id3 nvarchar(1000) = (select $node_id from [人] where [名前] = N'Cさん') declare @id4 nvarchar(1000) = (select $node_id from [人] where [名前] = N'Dさん') declare @id5 nvarchar(1000) = (select $node_id from [人] where [名前] = N'Eさん') insert into [好き] values (@id1, @id2) , (@id2, @id3) , (@id3, @id2) , (@id4, @id5)
まず繋がってる人を取ってみます。
select [誰さん].[名前] as [誰々さんが], [好きな人].[名前] as [好きな人] from [人] [誰さん], [好き], [人] [好きな人] where match ([誰さん] - ([好き]) -> [好きな人])
誰々さんが | 好きな人 |
---|---|
Aさん | Bさん |
Bさん | Cさん |
Cさん | Bさん |
Dさん | Eさん |
ここから、両想いの Bさん、Cさんを除くと求めたい片思いの人が取れます。
not match (誰さん <- ([好き]) - [好きな人])
を追加したら良いのかなと試したところエラーが出ました。
select [誰さん].[名前] as [誰々さんが], [好きな人].[名前] as [好きな人] from [人] [誰さん], [好き], [人] [好きな人] where match ([誰さん] - ([好き]) -> [好きな人]) and not match ([誰さん] <- ([好き]) - [好きな人])
メッセージ 13903、レベル 16、状態 1、行 23 エッジ テーブル '好き' が複数の MATCH パターンで使用されています。 メッセージ 13905、レベル 16、状態 1、行 23 MATCH 句は、OR や NOT を使用して他の式と直接組み合わせることができません。
MATCH は、OR や NOT と一緒に使えないようです。
Graph extensions in Microsoft SQL Server 2017 and Azure SQL Database
にも記載がありました。
スライドの P32-34 辺りです。
というわけで書き直します。
select [誰さん].[名前] as [誰々さんが], [好きな人].[名前] as [好きな人] from [人] [誰さん], [好き], [人] [好きな人] where match ([誰さん] - ([好き]) -> [好きな人]) and not exists ( select * from [好き] [nest] where match ([誰さん] <- ([nest]) - [好きな人]) )
誰々さんが | 好きな人 |
---|---|
Aさん | Bさん |
Dさん | Eさん |
これで取れました!
もう1個のエラーの エッジは1個のマッチでしか使えないのも少し試します。
両想いを取るこれでもエラーが出ました。
select [誰さん].[名前] as [誰々さんが], [好きな人].[名前] as [好きな人] from [人] [誰さん], [好き], [人] [好きな人] where match ([誰さん] - ([好き]) -> [好きな人] and [誰さん] <- ([好き]) - [好きな人])
正しくはこうなります。
select [誰さん].[名前] as [誰々さんが], [好きな人].[名前] as [好きな人] from [人] [誰さん], [好き] [好1], [人] [好きな人], [好き] [好2] where match ([誰さん] - ([好1]) -> [好きな人] and [誰さん] <- ([好2]) - [好きな人])