🦔
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
テーブル2
正常なクエリ例
ここで一方をGROUP化してJOINすることを考える。
GROUP BY
とSELECT
の順序を一致させたクエリでは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独自の問題っぽい。
対応方法
-
SELECT
とGROUP BY
の列の順序を常に一致させる - JOIN句で明示的にキャストする(
CInt()
やCLng()
)
どっか資料とかないんかな。
Discussion