SPSS Modelerの整数の範囲

SPSS Modelerの整数の範囲について調べてみました。

マニュアルには明記がないようです。
https://www.ibm.com/docs/ja/spss-modeler/18.5.0?topic=datatypes-integers

調べた結論としては以下のようです。
* 表示や演算可能なのはBIGINTの範囲(19桁)
* ユーザー入力で入力できるのはLONGの範囲(10桁)。演算はBIGINTの範囲で可能
* Db2のINTEGER型、LONG型は整数型として処理可能。ただし、INTEGER型のデータが演算後にオーバーフローする場合はあらかじめBIGINTに変換しておく必要がある。
* Db2のDECIMAL型は10桁を超えると文字列型として読み込まれるが、BIGINT（19桁）の範囲まではto_integerで変換して整数として扱うことが可能。それ以上大きい整数は整数として扱うことはできない。



# ユーザー入力での最大はLONG
ユーザー入力でLONG範囲のデータは入力できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/a6f53891-bd80-7e74-a5a1-b35c066061c7.png)

LONGの最大値を超える値をいれると、「 フィールド 'INT' に不正な値が指定されています: 2147483648」というエラーになりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/19a39d09-eeac-5447-78fa-ed7280448dee.png)

# 演算の最大はBIGINT
元データは0と1で用意しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/8a5235a0-80c0-755d-bee6-e4e1018fa144.png)

以下を足しこんでみました。
LONGの最大値：2147483647
LONGの最大値＋１:2147483648
BIGINTの最大値:9223372036854775807

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/1349f1f9-a7e0-af98-302f-447672800f9a.png)

結果としてはLONGを超えてもBIGINTの最大値までは正しく演算できています。
一方で、BIGINTの最大値を超える「1+BIGINTの最大値」の演算結果は「-9223372036854775808」というBIGINTの最小値になってしまっておかしな結果になっています。オーバーフローしたためと思われます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/4d371150-c528-1159-833a-6c19a54751ca.png)

なお、値として「BIGINTの最大値＋１」を足しこもうとすると「AEQMJ0422E: CLEM エラー: 次の式の数値 '9223372036854775808' は範囲外です: INT+9223372036854775808」でCLEM式自体がエラーになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/f8419615-dbd0-a6e5-5e17-ba9fc91d2b33.png)

# Db2　INEGER型とBIGINT型の読み込み
以下のようなテーブルをDB2に用意しました。
```sql
create table LARGEINT(LI INTEGER, BI BIGINT);
INSERT INTO LARGEINT VALUES(2147483647,9223372036854775807);
```

どちらも整数型として問題なく読めています。ユーザー入力と異なり、BIGINTのサイズのデータも整数型として問題なく認識できています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/4bccc7f7-8d8c-94a6-d437-0df9f06afcc5.png)

# Db2 INEGER型とBIGINT型の演算も可能
以下のようなテーブルをDB2に用意しました。元の値は０です。
```sql
create table INT0TEST(LI INTEGER, BI BIGINT);
INSERT INTO INT0TEST VALUES(0,0);
```

ユーザー入力同様にBIGINTの範囲で演算できています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/bddb6d09-fa93-2df5-d1de-af82b8f907bd.png)

しかしながら、以下のようにもともと1という値が入っていて、演算後にLONGの範囲を超える場合はOverflowのエラー（SQL0802N Arithmetic overflow or other arithmetic exception occurred. SQLSTATE=22003）になりました。
```sql
CREATE TABLE INT1TEST(LI INTEGER, BI BIGINT);
INSERT INTO INT1TEST VALUES(1,1);
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/a1d6357b-c0c6-8dd2-f23f-1edc37982e93.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/31113d47-0261-995f-90c6-0b6050c1c654.png)

演算前にLONGの範囲が超えることがわかっている場合はDb2が自動的にBIGINTに型を変えているのですが、演算前にそれがわからない場合はLONG型のままなのでエラーになるようです。

これを回避するためには、いったんto_stringをかけてからto_integerをすることでBIGINT型にして演算すればOKです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/d9e888d9-abfe-c4c0-f693-0f5fae1e1eb9.png)

# Db2　DECIMAL型の読み込み

RDBでは整数でもDECIMAL型を使うことも多いと思います。Db2の場合最大31桁まで扱えますので、BIGINTよりも大きな整数を扱うことができます。

以下のようなテーブルを作ってみますLIは10桁でLONGの範囲、BIは19桁でBIGINTの範囲、LN31はDECIMALでしか表現できない31桁です。

```sql
CREATE TABLE LARGENUMBER(LI DECIMAL(10), BI DECIMAL(19), LN31 DECIMAL(31));
INSERT INTO LARGENUMBER VALUES(1234567890,1234567890123456789,1234567890123456789012345678901);
```
10桁の列LIは整数型として読まれましたが、列BIと列LN31は文字型扱いになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/117e5b5c-414b-60a9-e903-ce2d2e882b94.png)

列BIについてはto_integerで変換することによって整数型にすることができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/3603dd4d-e5ff-0e2c-9152-673f2bdea21f.png)

SQLを確認してみると「CAST(T0.BI AS BIGINT) AS BI」でBIGINTに変換しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/efa2570f-ae49-501b-1b12-c568bf1be06f.png)

BIGINTの範囲を超えてしまう列LN31はto_integerしようとすると、「CAST(T0.LN31 AS BIGINT) AS LN31 」がOverflow(SQL0413N Overflow occurred during numeric data type conversion. SQLSTATE=22003)で失敗します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/fae5b7f6-1107-17bf-2324-439598105536.png)

to_numberをつかうと連続型にはなりますが、浮動小数点型になってしまいます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/d6c2ee2f-9609-f4f2-b691-7fdbb697ecb4.png)

そのため浮動小数点誤差が発生してしまい、元のデータを維持することができません。やはりBIGINT以上の整数は扱えないということになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/4bc6a35b-4a28-25df-b214-89fabd7ae141.png)

# サンプル
* テスト環境
    * Modeler 18.5
    * Windows 11 64bit
    * Db2 Warehouse on Cloud

* サンプルストリーム

https://github.com/hkwd/spsssample/raw/master/240209Integertest/Integertest.str

# 参考
#### Db2の数値型 - IBM Documentation 
https://www.ibm.com/docs/ja/db2/11.5?topic=list-numbers