AlteryxのTipsを不定期にお届けしている週間(?)AlteryxTipsです。
今回は、Advent of Code 2025のDay5からヒントをもらった内容についてお届けしたいと思います。
Advent of Code 2025のDay5では、重複した範囲を除去するというのが課題でした。つまり、以下のようにハイフン区切りで値の範囲が与えられた時、明らかに重複が見られると思います。
1-100
2-2
2-3
2-4
10-12
101-110
108-120
110-115
111-112
200-210
201-209
202-212
この重複をどのようにして除去すれば良いでしょうか?(データの特性として、ハイフンの左側の数値の方が右側の数値より必ず小さい、とします。そうでない場合であってもMax、Min関数を使えばすぐにその状態に持っていくことができます)
一般的に思いつくのが、すべての値の範囲を行生成ツールで作成し、重複を取り除いてから連続した値をグループとして再グルーピングする方法です。

しかしこの値自体がバカでかい場合(桁数が非常に大きい場合)、全ての値を作るとワークフローがめちゃくちゃ重くなってしまいます(例えば桁数が9桁だと億レベルになるので、非常に大量のレコードになってしまいます)。
つまり、汎用的に使えるようにするためには範囲をうまく加工していく必要があります。
範囲の重複を除去し範囲をまとめる
まずこの形まで持っていきましょう。ワークフローは上の基本的なソリューションで紹介したものと途中まで同じです。

ここから、この範囲の全パターンを作成し、範囲がかぶっているかどうかIF文で検査し、かぶっていれば統合していく、という反復マクロを使ったものもできますが、今回は複数行フォーミュラ中心のマクロなしソリューションでやってみましょう。
まず、左側の数字の小さい順に並び替えます。もちろん大きい方の数字も小さい順に並び替えましょう(すでにもうそうなっていますが・・・)。
ここからのやり方は色々あるのですが、私のアルゴリズムは以下のとおりです。
- 新しく大きい方の数値を作ります
- 小さい方の数字をアップデートします
- グループ化します
- グループごとに最小値、最大値を取る
1.新しく大きい方の数値を作ります
複数行フォーミュラツールで、最大値を更新します。小さい方の数を昇順に並べ替えた時に、大きい方の数が逆転しているということは、そこまでの数値は全部取れているということになるので、この性質を使っています。

設定はめちゃくちゃシンプルです。

Max([2], [Row-1:NewMax])
2.小さい方の数字をアップデートします
1で作成した大きい方の数字が、次のレコードの小さい方の数字を超えていたら、大きい方の数字で更新します。

IF [Row-1:NewMax]>=[1] THEN [Row-1:NewMax]
ELSE [1] ENDIF
これでこのような感じになります。

3.グループ化します
ここで、グループ化していきます。上のデータの2~4行目など不要なので統合したいです。また、整数前提であれば、6と7行目を統合したほうがすっきりします。このために、ある行の最大値と次の行の最小値を比較し、1差以内であれば同じグループにします(整数でないのであれば、同じときだけ同じグループにします)。

IF [Row-1:NewMax]+1=[NewMin] OR [Row-1:NewMax]=[NewMin]
THEN [Row-1:RangeGroup]
ELSE [Row-1:RangeGroup]+1 ENDIF
4.グループごとに最小値、最大値を取る
集計ツールで、グループごとに最小値、最大値を取ります。

これできれいにまとまりました!

元々の値のレンジがどこに属するか、というのは3と4の結果を結合すれば得られます。
また、2の次に集計ツールで以下のようにグループ化することでも実用的な回答は得られます。

基本的に範囲は被ってないのでこれでも問題ないように思います(正確に言うと、110、210とつなぎ目が被ってますが・・・)。

ワークフロー全体は以下のとおりです。

グループがある場合
元データが単なる値の範囲だけではなくて、値の範囲ごとにカテゴリがあるとします。

このときカテゴリが違う場合に混ぜたくなり場合はグループを示す列をグループ化オプションに組み込めばオッケーです。

上のように、それぞれの複数行フォーミュラツールに仕込む必要があります。また、集計ツールも同様です。詳細はサンプルワークフローをごらんください。
まとめ
- 値の範囲を与えられた時に、この重複範囲を取り除く方法をご紹介しました
- 何かしら実際の業務でも使いそうなのでちょっと汎用的に作ってみた感じです
- 逆に重複部分だけ取り出したいことも・・・あるんですかね?

コメント