例えば、AA-01、AA-02、AB-01、AB-02、AC-01,AC-02…、ZZ-02など分類が入力された「分類」というカラムがあり、
後続の作業のために、これらの分類を数字に変化にしたフラグ(AAから始まるものは「1」に、ABから始まるものは「2」に、ACから始まるものは「3」に)を建てた「フラグ」というカラムを建てる目的で、
IIf(Left([分類],2)="AA"),1,IIf(Left([分類],2)="AB"),2,IIf(Left([分類],2)="AC"),3,Left([分類],2)="AD"),4,……))))))))
という式をたてたのですが、
「閉じかっこが多すぎます」というようなメッセージが出て実行できませんでした。
IIf関数を使う以外で、○○の場合なら、××を返すというパターンが大量にある場合のクエリの式を建てることは可能なのでしょうか?
分かりにくくて大変申し訳ないのですが、よろしくお願いいたします。
下記、どうでしょうか?
Switch関数 - もう一度学ぶMS-Access
りんご様
返信ありがとうございます。
switch関数で動くことは確認できたのですが、場合分けの数を増やしていったところ、16個ほどの条件で、指揮が複雑すぎます、というエラーが出るようになりました。
他に手法はないのでしょうか?(そもそもaccessはそういうツールではないし、Excelでやればどうにかなるのですが…)
ご教授いただけますと幸いです。
よろしくお願いいたします。
ある属性X( 1 )を決めると、他の属性Y( AA )の値が一意に決まる
ある属性X( 2 )を決めると、他の属性Y( AB )の値が一意に決まる
ある属性X( 3 )を決めると、他の属性Y( AC )の値が一意に決まる
...
場合、「 Y は X に関数従属している 」といいます。
Y の種類が少数の場合は
IIf関数やSwitch関数を使って X を定義するのもいいでしょうけど
Y の種類が多い場合や、今後、Y の種類が増えることが想定される場合は
テーブル設計を見直したほうがいいでしょう。
`
sql入力ID COUNTER NOT NULL PRIMARY KEY
, 分類 VARCHAR( 50 ) NOT NULL
);
SELECT y.入力ID
, y.分類
, x.分類CD
FROM t_分類マスタ x
, t_分類トラン y
WHERE x.分類名 = Left$( y.分類, 2 )
ORDER BY 1 ;
この回答は、お遊びですので、軽く流して下さい。
テーブル1:フィールド1(短いテキスト型)
テーブル2:フィールド1(短いテキスト型)・・・テーブル1をコピペして下さい。
クエリ1(テーブル作成クエリ)
テーブル作成クエリを実行したら、1列目にオートナンバー型のフィールド「カラム」を挿入して下さい。データシートビューに切り替えると、オートナンバリングが実行されます。
英字分類のテーブル
同じ要領で、数字分類(短いテキスト型)のテーブルを作ります。
数字分類のテーブル
※最初のレコード、00は削除して下さい。
最後に、英字分類テーブルをテーブル1、数字分類テーブルをテーブル2に見立て、同じ要領で進めて下さい。
クエリの途中経過
( 続き ) 理想は
`
sql入力ID COUNTER NOT NULL PRIMARY KEY
, 分類CD INT NOT NULL
, 分類別番号 INT
);
SELECT y.入力ID
, y.分類CD
, y.分類別番号
, x.分類名 & Format$( y.分類別番号, '-00' ) As 分類
FROM t_分類マスタ x
INNER JOIN t_分類トラン y
ON x.分類CD = y.分類CD
ORDER BY 1 ;
mayuさんに質問なんですが、なぜ
分類CD
がPRIMARY KEY
なんでしょう?文字に対して番号を割り当てるなら
分類名
側をPRIMARY KEY
としたほうがそれっぽいと思うのですがhirotonさん、ご質問ありがとうございます。
分類CDをPRIMARY KEYとする理由を3つほど述べますね。
[理由1.]
PRIMARY KEY はソートに利用することが多いから、です。
文字列ですと、全行パディングされていない限りソートが難しくなります。
また、列数が2つのテーブルに
PRIMARY KEY と INDEX 両方を付与するのは
DBの容量増加、UPSERTの遅延、INDEX破損率の上昇
といったリスクを抱えることになりますので
列数の少ないマスタテーブルでは、設計上の理由から回避したいです。
( 経験則上、テーブルの破損 = INDEXの破損 が圧倒的に多いです )
[理由2.]
( あくまで可能性として )分類の再編が発生して
サロゲートキーを利用する一因として
理由2.のように、主キーの体系が変化した場合などの影響が
ナチュラルキーに比べて( サロゲートキーのほうが )少なくなります。
んー、質問の内容に対応する場合と、新規で構築する場合とで話も変わってくるとは思うんですが>> 3の段階の話だと
こういう登録が許容されるテーブルを使うのはどうかと思うんですよね
改めて構築するということだと分類CDがどこまでサロゲートキーとして有効かというのもあって、可能性の話なら
もあり得るんじゃないでしょうか。質問上だと、「フラグ」というカラムにしたいということなので
この形でサロゲートキーな分類CDを使うならわかるんだけどという感じです
分類名の重複は、データの登録前後ともに、集計クエリ・DCountのような定義域集計関数で
誤りをチェックできるため、設計上問題ないという見解です。
私とhirotonさんで質問文の解釈に違いがありそうです。
mabeeさんは、( おそらく )便宜上「フラグ」と表現されましたけど
通常、フラグという言葉は、立つ・折るという
二者択一に近い条件分岐や選択で用いられます。
分類を文字列だけでなく、数値でも表現したい とご希望なのは
並び替えの基準となる「識別子」が必要とお考えになったのではないか
と推測しました。
したがって、私は{ フラグ = 識別子 }と解釈し、識別子を主キーとしています。
( 分類CD, 分類名, フラグ の3列構成にしない理由にもなっています )
また、余談にはなりますけど
分類をキーとした場合は、差別化を図るかどうかは別として
AA, Aa, aA, aa AA それぞれを異なる値として扱えません。
( バイナリ比較が必要になり、カラムも GUI では作成不可 )
( 差別化を図る場合は>> 3の回答自体が無効という盛大なブーメランですね )
数値型フィールドを識別子とすれば、全角半角大文字小文字を
同一の値で扱うことも差別化も容易で、高度なスキルも必要ありません。
常時バイナリ比較になり、経験の浅いDBAでも扱いが容易なことから
値の識別となる大小比較や結合・並び替えは、できる限り文字列より数値で実施するべき
というのが私のポリシーですので
>> 3でのSELECT文も、苦肉の策に近く、ベストプラクティスではない
というのが本音にはなりますね。
下記のようなテーブルを作成します。
テーブル名 T_フラグ
`
`
mayuさんとがぶっちゃいました。
かつ、mayuさんの方が完璧かつ詳細な回答でした。
mayuさんの回答を参考にしてください。
>> 7
こんな感じになるのでしょうか?
親テーブル:英字分類No、英字分類、(英字分類Noで決まる)分類名
単独主キー AAとABなど、頭文字がAで始まるが、特に意味はない。
子テーブル:英字分類No、数字分類、(英字分類Noと数字分類で決まる)分類名
複合主キー AA01とAB01など、下2桁の行番号に、特別な意味はない。
分類フィールドは、導き出せるので、基本的にテーブルに保管しなくていいと思います。
用途が不明ですが、完ぺきな対応関係(ZZ=676)なら26進数から10進数への変換なんで
で表せますね
>> 8
明日、来週、来月、来年、いつか振り返った時のためにメモさせて下さい。
AA-02→ AB-011→ 202→ 01じっとみているうちに、思い出してきただろうか?
もともとのオリジナルは、こんな感じでした。
1→ 2 ❌02→ 01 ❌AA-02→ AB-01 ❌きっと、見えない、忘れた、気づかないんだと思う。
アレンジするなら、制約を組み込んでおかないと、おかしくなる.
テクニックを使ってアレンジするのは、大変。パッと見てもわからないし、オリジナルの事を忘れるし、そもそも気づかれない。