🦔

AccessでGROUP BYの順序を変えるとJOIN結果がおかしくなる(Access365/2016)

に公開

結論

Access(Access365 ビルド2410 / Access2016)では、GROUP BY句の並び順とSELECT句の順序が一致しない場合に、JOIN結果が壊れるという不可解な挙動を確認。
挙動を確認できた条件は以下の通り。

  • GROUP BY句で文字列、数値の順に指定している。
  • SELECT句でGROUP BYとは異なる順序で指定している。

普通はGROUP BY句で指定した順序に合わせるから問題ないと思うけど...。

前提

テーブル定義

以下のようなテーブルを用意。

CREATE TABLE テーブル1
(
    ID COUNTER PRIMARY KEY,
    数値1 INT,
    文字1 CHAR(255)
)

CREATE TABLE テーブル2
(
    ID COUNTER PRIMARY KEY,
    数値2 INT,
    文字2 CHAR(255)
)

テーブルの中身(例)

テーブル1
テーブル1
テーブル2
テーブル2

正常なクエリ例

ここで一方をGROUP化してJOINすることを考える。
GROUP BYSELECTの順序を一致させたクエリではJOINが正しく動作するが...。

SELECT  *
FROM
(
	SELECT  数値1,文字1
	FROM テーブル1
	GROUP BY 数値1,文字1
) AS t1
INNER JOIN テーブル2 AS t2
ON t1.数値1 = t2.数値2;

結果:

GROUP化してJOIN(正常)

異常なクエリ例

GROUP BYの順序を入れ替えるだけでJOIN結果が壊れる:

SELECT  *
FROM
(
	SELECT  数値1,文字1
	FROM テーブル1
	GROUP BY 文字1,数値1
) AS t1
INNER JOIN テーブル2 AS t2
ON t1.数値1 = t2.数値2;

結果:

末路

原因(の推測)

  • AccessではGROUP BYの順序が内部的なデータ型解釈や並び順処理に影響する?
  • 文字列→数値の順でGROUP BYを行うと、数値列が文字列として解釈される?
    • 実際、JOIN条件をCInt()で強制変換すると正常に動作する(ON CInt(t1.数値1) = t2.数値2)
    • とはいってもON t1.数値1 = CStr(t2.数値2)とすると型が不一致なので、文字列ではないんだけど。

いずれにせよAccess独自の問題っぽい。

対応方法

  • SELECTGROUP BYの列の順序を常に一致させる
  • JOIN句で明示的にキャストする(CInt()CLng())

どっか資料とかないんかな。

Discussion