警告: SQL標準でない GROUP BY クエリで間違った結果が返る
対象バージョン
InterSystems IRIS および IRIS for Health: 2019.1.0 以降
対象プラットフォーム すべて
InterSystemsは、間違ったクエリ結果が返る問題を修正しました。この問題は上記の InterSystems 製品のバージョンで発生する可能性があります。
問題の詳細
以下のすべての条件をみたした場合、クエリ結果が不正確な可能性があります。
- GROUP BY を使用し、かつ、COUNT などの集計を使って「いない」
- GROUP BY で指定して「いない」フィールドを SELECT で指定し(*)、かつ、そのフィールドが WHERE 条件に含まれている
- 単一のインデックスによりクエリ結果が取得でき、かつ、そのインデックスが GROUP BY で指定されたフィールドから始まっている
(*) グループ化していないフィールドを SELECT に含めることは、 InterSystems SQL独自の拡張であり、SQL標準でないことにご注意ください。
この問題により、上記をみたすクエリでは WHERE 条件が結果に正しく反映されません。すなわち、条件をみたさない行を含むクエリ結果を返すことになります。
なお、この警告の最後に、問題の影響を受けるクエリと受けないクエリ例を掲載しています。
解決方法
この問題は修正ID: AK1043 で解決します。この修正は今後リリースされるInterSystems IRIS および IRIS for Health 2020.1.2 や 2021.1.1 を含むすべての製品に含まれる予定です。また、お客様のご要望により、修正を現在お使いの製品に対するパッチとして個別に作成してご提供することが可能です。
※HealthShare をお使いのお客様へ
InterSystems にて HealthShare ファミリーの製品をレビューした結果、上記条件をみたすクエリは、製品内部で使用されていないことが判明しました。
ただし、HealthShare 製品とは別に InterSystems IRIS 機能を使われているお客様は、ご自身で作成されたアプリケーションやカスタマイズがこの問題の影響を受けるかご確認いただく必要があります。
クエリ例
本問題の影響に関するクエリ例をお伝えします。
ここでは test.TestTable テーブル を用いて説明します。テーブルには 3つのInteger プロパティと 1つのインデックスが、以下のように定義されています。
Property Int1 As %Integer;
Property Int2 As %Integer;
Property Int3 As %Integer;
Index GroupBy On (Int1, Int2);
影響を受けるクエリ
- SELECT Int1, Int2 FROM test.TestTable WHERE Int2 > 1 GROUP BY Int1
このクエリは上記の条件をみたすため、本問題の影響を受けます。そのため Int2 <= 1 の行も誤って表示されます。 - SELECT Int1, ID FROM test.TestTable WHERE Int2 <= 1 GROUP BY Int1
このクエリも本問題の影響をうけます。IDがインデックスに含まれるため結果をインデックスから直接取得できるからです。 そのため Int2 > 1 の行も誤って表示されます。
影響を受けないクエリ
- SELECT Int1, Int2 FROM test.TestTable WHERE Int2 > 1
GROUP BY を使用していないため、影響を受けません。 - SELECT Int1, Int2, COUNT(*) FROM test.TestTable WHERE Int2 > 1 GROUP BY Int1
COUNT 集計を使用しているため、影響を受けません。 - SELECT Int1, Int2 FROM test.TestTable WHERE Int1 > 1 GROUP BY Int1
- SELECT Int1, Int2 FROM test.TestTable GROUP BY Int1
いずれのクエリも「GROUP BY で指定していないフィールドが WHERE 条件に含まれている」条件にあてはまらないため、影響を受けません。 - SELECT Int1, Int2 FROM test.TestTable WHERE Int1 > 1 GROUP BY Int2
テーブルの複合インデックスが GROUP BY で指定しているフィールドから 始まっていないため、影響を受けません。 - SELECT Int1, Int2 FROM test.TestTable WHERE Int2 > 1 AND Int3 > 1 GROUP BY Int1
- SELECT Int1, Int3 FROM test.TestTable WHERE Int2 > 1 GROUP BY Int 1
いずれのクエリも Int3 フィールドを使っており、このフィールドはインデックスに格納されていません。つまり、このクエリは、インデックスのみから 結果を取得できないため、影響を受けません。