エディタでボタンポチポチっていう操作だから、手続きの積み重ねのような動作をしているように思ってしまうかもしれない。ヒトはその方が理解しやすいだろうし、クエリの定義もしやすいってことなのでしょう。だけど、Power Query の中の人 Mashup engine の動作は異なる。
Mashup engine がクエリを評価するとき、その評価結果や途中経過を保存することはない。クエリに定義された処理に必要と判断されれば一時的にキャッシュすることがあるだけだし、Power Query エディタでステップごとに参照できる状態はプレビューであって評価結果や途中経過でもない。
"テーブルは行ごとに処理される" という動作は、 ストリーミング という Power Query の基本的な/動作ふるまいのうちのひとつだ。ストリーミングを説明しやすいのでタイトルとして取り上げた。
たとえば
ストリーミングは Table.AddColumn に限ったはことではないけど、わかりやすいので。
テーブルに列の追加するとき行われる処理について
// Query1
let
Source = Table.FromColumns(
{
List.Numbers( 1, 5 )
},
type table [Column1 = nullable Int64.Type]
),
AddedColumn2 = Table.AddColumn(
Source, "Column2",
each [Column1] + 10,
Int64.Type
),
AddedColumn3 = Table.AddColumn(
AddedColumn2, "Column3",
each [Column1] * 10,
Int64.Type
)
in
AddedColumn3
というクエリの結果は、5行3列のテーブルになる。Power Query エディタでのステップは、
- Source: 5行1列のテーブル
- AddedColumn2: 列を追加
- AddedColumn3: 列を追加
となるが、5行のテーブルに列が追加されるのではなく、行ごとで列を追加する動作を5回繰り返す。
この動作ができないとステップごとに途中経過を保存することが必要になり、メモリがどれだけあっても足りなくなるから、行ごとの処理は合理的な動作。
クエリを分割しても同じ
このクエリのステップをそれぞれ個別のクエリに分割しても動作は変わらない。
// Query2_1
let
Source = Table.FromColumns(
{
List.Numbers( 1, 5 )
},
type table [Column1 = nullable Int64.Type]
)
in
Source
// Query2_2
let
Source = Query2_1,
AddedColumn2 = Table.AddColumn(
Source, "Column2",
each [Column1] + 10,
Int64.Type
)
in
AddedColumn2
// Query2_3
let
Source = Query2_2,
AddedColumn3 = Table.AddColumn(
Source, "Column3",
each [Column1] * 10,
Int64.Type
)
in
AddedColumn3
思ったこと🙄
そもそも、Power Query エディタの追加編集したステップの順で処理されるとは限らない のである。
その他