メモ T-SQL INSERT - SELECT で登録された IDENTITY と 元データの値を紐づける

以前調べたのをメモってなかったので + 使おうかなと思う機会があったのでメモ。

昔調べた時の元ネタはこちら

output を使って書きたいけど、シンプルに書けないのがネック。。
OUTPUT 句 (TRANSACT-SQL) | Microsoft Docs

from_table_name
DELETE、UPDATE、または MERGE ステートメントの FROM 句に含まれるテーブルを指定する列プレフィックスです。更新または削除する行を指定するために使用します。 

output で返す対象が、delete, update, merge のときだけ、from_table_name 使えるって書いてあるので、insert も無理やり merge で書く感じ。

stackoverflow にも…
sql server - What columns can be used in OUTPUT INTO clause? - Stack Overflow
on (1 = 0) に違和感なければありなんかなー。


を拝借して、merge で書き換えたのをメモっとく。

DECLARE @registered AS TABLE (Id bigint, A int, B int);

MERGE Table2 dest USING SELECT A FROM Table1 src on (1 = 0)
WHEN NOT MATCHED THEN INSERT (A) VALUES (src.A)
OUTPUT INSERTED.Id, src.A INTO @registered
;
/*
INSERT INTO Table2 (A)
OUTPUT INSERTED.Id, INSERTED.A, t1.B INTO @registered -- ここに t1.B は書けない
SELECT A FROM Table1 AS t1
;
*/
 
INSERT INTO Table3 (Id, B)
SELECT r.Id, r.B FROM @registered AS r

12/2(土) 第22回 中国地方DB勉強会 in 出雲 で SQL Server 2017 のお話しします

第22回 中国地方DB勉強会 in 出雲 - connpass

今回は PostgreSQL 10、MySQL 8.0、SQL Server 2017と新しめのお話しをテーマにした勉強会です。
私は SQL Server 2017 のお話しをさせていただきます。

出雲行くの初めてじゃないかな?
神在祭のご案内 - 出雲大社 と被ってるためか宿が中々無いですが、
是非ご参加を~。

SQL Server 2017 の Graph データベースのお話しをしました。

プログラミング生放送勉強会 第49回@大阪 + わんくま同盟 大阪勉強会 #71 : ATND で話したスライドです。

デモで使ったクエリとか
https://1drv.ms/f/s!Amu3DIZBpTxRsyyBYVenLayAxKNQ

11/18(土) プログラミング生放送勉強会 第49回@大阪 + わんくま同盟 大阪勉強会 #71 でお話しします

今週土曜の
11/18 プログラミング生放送勉強会 第49回@大阪 + わんくま同盟 大阪勉強会 #71 開催 – プログラミング生放送
SQL Server 2017 の Graph データ に焦点を当ててお話しします。

他にも、MvvmCross、メタプログラミング、Docker コンテナの話しと盛り沢山です!

申し込みサイトはこちら
プログラミング生放送勉強会 第49回@大阪 + わんくま同盟 大阪勉強会 #71 : ATND

プロ生今年初の大阪開催です!まだ空きありますので是非ご参加を~。

メモ $node_id 列に インデックス貼ると、内部では graph_id_<hexstring> に列になるか試してみた。

ドキュメントに書いてたから試しただけ。

SQL Graph Architecture | Microsoft Docs
Node Table より引用

That is, an index created on the $node_id column, will appear on the internal graph_id_<hex_string> column. 
create table Hoge (
  Name nvarchar(20) not null primary key
) as node
create index idx_Hoge_NodeId on Hoge ($node_id)

select idc.column_id, col.name
from 
  sys.indexes id inner join sys.index_columns idc on 
    id.object_id = idc.object_id and id.index_id = idc.index_id
  inner join sys.columns col on 
    idc.object_id = col.object_id and idc.column_id = col.column_id
where id.name = 'idx_Hoge_NodeId'
column_id name
1 graph_id_03ED99AB760344ACADAE09BE9D4478E4

おーほんとだ。

メモ:SQL Server 2017 Graph の NOT MATCH

ぼちぼち SQL Server 2017 の Graph 触ってます。
Graph processing with SQL Server and Azure SQL Database | Microsoft Docs

MATCH は、NOT 書けないようなので、代わりに NOT EXISTS を使うようです。
MATCH (SQL Graph) | Microsoft Docs

例:片思いの人を取得する。
f:id:odashinsuke:20171031231232p:plain
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]) - [好きな人])

10/24(火) SQLWorld★大阪#44 開催します

SqlWorld :: SQLWorld★大阪#44 開催します。26回目の平日夜開催で、前回同様 ハンズオン 形式行う予定です。

【日時】
2017年10月24日(火曜日) 19:00~21:00
 

【イベント概要】
SQLWorld 26回目の平日夜開催~。今回も、みんなで SQL を書いてみようというハンズオン企画です!ブラウザがあれば参加出来るようにしていますので、iPad 等のタブレットでも大丈夫です。
 

【会場】
フェンリル株式会社さま大阪本社 http://www.fenrir-inc.com/
〒530-0011 大阪府大阪市北区大深町 3番1号 グランフロント大阪タワーB(オフィス)
 

【参加費】
無料
 

【持ち物】
パソコン/タブレット (DB のインストールは不要です。)
 

【参加可能人数】
13 人
 

お題に沿って、SQL を書いてみようという勉強会です。是非ご参加を~。

開催回数は増えていっていますが、続き物というわけでは無いので初めて参加される方でもお気軽にどぞー。