Splunk: 集計処理におけるNULLの扱いについて


###### 実施環境： Splunk Free 8.2.2

### 0. 概要

 Splunk では対象のフィールドに値が入っていない場合、 NULL として扱われます。
この NULL は、空文字列や 0 とは明確に別のものです。
今回は集計処理においてこの NULL を処理した場合の挙動について紹介していきます。

### 1. 使用するデータ

今回は、以下のデータをもとに確認していきます。

```Splunk:Splunk
| makeresults count=3
| streamstats count AS CNT
| eval NULL  = if( CNT == 1, null(), CNT),
       EMPTY = if( CNT == 2, "", CNT),
       ZERO  = if( CNT == 3, 0, CNT)
| fields - CNT, _time
```

![WS000157.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/42cf15d9-ff0c-6be5-0bb5-5bd227cee376.jpeg "元データ")

| EMPTY | NULL | ZERO |
|-:|-:|-:|
| 1 | (NULL) | 1 |
| (空文字列) | 2 | 2 |
| 3 | 3 | 0 |

### 2. 集計値に使用した場合

集計値に NULL を使用した場合、集計は NULL を除外したデータを母集団として行われます。
例えば下記の例の avg(NULL) の場合、 NULL 値の1行目は母集団から除外され、2行目と3行目のみで平均値をとって(2+3)÷2=2.5となります。
空文字列の場合も同様です。

```Splunk:Splunk
| makeresults count=3
| streamstats count AS CNT
| eval NULL  = if( CNT == 1, null(), CNT),
       EMPTY = if( CNT == 2, "", CNT),
       ZERO  = if( CNT == 3, 0, CNT)
| fields - CNT, _time
| stats avg(NULL), avg(EMPTY), avg(ZERO)
```

![WS000159.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/7bda6796-619d-f5ce-6f06-26163cd6e446.jpeg "集計値")

### 3. 集計キーに使用した場合( stats コマンド)

集計キーとして stats コマンドの BY 句や chart コマンドの OVER 句に指定した場合、指定した項目のうち1つでも NULL であるデータは集計の対象から除外されます。
一方で空文字列であるデータは集計の対象に含まれます。
下記の例でも1行目の NULL を含むデータは集計に含まれていませんが、2行目の空文字列を含むデータは問題なく集計されています。

```Splunk:Splunk
| makeresults count=3
| streamstats count AS CNT
| eval NULL  = if( CNT == 1, null(), CNT),
       EMPTY = if( CNT == 2, "", CNT),
       ZERO  = if( CNT == 3, 0, CNT)
| fields - CNT, _time
| stats count BY NULL, EMPTY, ZERO
```

![WS000158.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/5a89c50e-c7a7-a979-72e1-9f2253064be1.jpeg "stats")

### 4. 集計キーに使用した場合( chart , timechart コマンド)

集計キーとして chart コマンドや timechart コマンドの BY 句に指定した場合は、 stats コマンドと異なり NULL 値も集計対象に含まれ、列名は「 NULL 」となります。
空文字列も同様に集計対象に含まれ、こちらは列名は「 VALUE 」となります。
下記の例でも NULL 、空文字ともに集計されていることがわかります。

```Splunk:Splunk
| makeresults count=3
| streamstats count AS CNT
| eval NULL = if( CNT == 1, null(), CNT)
| fields - CNT
| timechart span=1h count BY NULL
```

![WS000203.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/ad41175a-f48b-ab75-1058-adf74c490670.jpeg "timechart_null")

```Splunk:Splunk
| makeresults count=3
| streamstats count AS CNT
| eval EMPTY = if( CNT == 2, "", CNT)
| fields - CNT
| timechart span=1h count BY EMPTY
```

![WS000206.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/f46496b0-94e2-f149-99e5-52cd5ad90245.jpeg "timechart_empty")

### 5. 集計キーに使用した場合( chart , timechart コマンド/オプション使用)

集計キーとして chart コマンドや timechart コマンドの BY 句に指定した場合、オプションを使用して NULL 値の処理を変更することが可能です。
 usenull オプションを false に指定すると、 NULL 値が集計対象から除外されます(デフォルトは true )。

```Splunk:Splunk
| makeresults count=3
| streamstats count AS CNT
| eval NULL = if( CNT == 1, null(), CNT)
| fields - CNT
| timechart usenull=false span=1h count BY NULL
```

![WS000221.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/ad89e945-3ef8-03c4-9cf9-ba458a11f58d.jpeg "usenull")

 nullstr オプションに文字列を指定すると、その文字列が NULL 値の列名に使用されます。

```Splunk:Splunk
| makeresults count=3
| streamstats count AS CNT
| eval NULL = if( CNT == 1, null(), CNT)
| fields - CNT
| timechart nullstr="なし" span=1h count BY NULL
```

![WS000222.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/1a4beac5-7e48-ddc3-0732-6b3c16ee8feb.jpeg "nullstr")