質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.93%

マスタからのデータ読込みで、キー項目が設定されていない場合は"その他"のデータを取得したい

解決済

回答 4

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,160

score 187

 実現したいこと

以下のようなマスタ設定を読み込む処理をなるべくシンプルに実現したいです。

・マスタは読み込むためのキー情報(IDとします)の他、レコードによって処理を分岐させるための属性(Propertyとします)を持つ。

ID Property Value
001 null ABC
002 true DEF
002 false GHI
003 null JKL

・上記の例の場合、ID="001" or "003"の場合はそれぞれ"ABC"および"JKL"をマスタの値として利用します。
・ID="002"の場合には、もうひとつのPropertyがtruefalseかで参照するマスタの値が変えたいです。

・Propertyを確認する必要がないマスタはnullとするなど、確認が不要であることが分かるような値になっています。

・Propertyについては、nullもしくはtrue / falseになる前提です。true / falseのものがあればnullのものより優先してtrue / falseの方を利用します。(上記にID="002"でPropertyがnullのものがあっても無視する。)

・bool型という例が悪かったのですが、Propertyは設定されている場合と設定されていない場合とで分けたいです。

 現行の処理

マスタ読込み処理の中で、まずPropertyも条件に含めたSELECT文を発行し、引きあたるものがあればそれを利用、引きあたらなければProperyを条件に含めないSELECT文を発行、という順序で処理を行っています。

select Value from Table01 where ID = "001" and Property = true


上記の結果が0件の場合のみ、

select Value from Table01 where ID = "001"


これでProperty値がnullのレコードを拾います。

 問題点

現行の処理だと、Propertyのような項目が増えた場合にSELECT文の発行回数が倍々に増えていきます。
まず、Propertyがtrue / falseに設定されているものを探し、無ければnullのものを探す処理を想定しています。
Property2ができると、まずPropertyおよびProperty2が存在するものを探し、そのあとどちらか一方のみが存在するものを探し、、、、といったような冗長な処理しか考えつかず、ご質問に至っております。

今、このPropertyにあたる項目の2つ目を追加したいのですが、現行処理が上記のようになっているためどうするべきか悩んでいます。

なお、DBからの取得に限った話ではなくAP内でも、取得する処理が冗長となってしまうことを懸念しております。
DBから一括で取得してきたものをAP内部で処理するにしても、まずPropertyが設定されているものを探して次にnullのものを…となってしまうのを効率よくできないかと悩んでおります。

以上、拙い文章で恐縮ですが、知恵を貸していただけますと助かります。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • PineMatsu

    2018/10/16 16:57

    これってC#ではなくSQLなどのデータベースクエリやアルゴリズムに関するものなので、そういうタグを付けたほうがいいと思います。

    キャンセル

  • YAmaGNZ

    2018/10/16 17:10

    Property値の仕様によってかなり話が変わってくる内容な気がします。上記の例でIDが"002"のものはProperty値がnullのレコードは絶対に存在しないのでしょうか?Property値が(null)もしくは(true/false)のどちらかなのであれば、上記のSQLも(Property = true or Property is null)の1回で行けそうですがそうしていない理由があるのかも不明です。ただ漠然と項目が増えた場合と聞かれても、その項目の仕様も分かりませんし、抽出条件も分かりませんので答えようがないかと思います。

    キャンセル

  • Zuishin

    2018/10/16 17:24

    null 要りますか? null の代わりに true でいいのでは?

    キャンセル

回答 4

checkベストアンサー

+2

まず ID も Property も多くの環境で予約語として使われますので、カラム名としては不適切です。
特にID/id/IdはRDBでは一般にサロゲートキーに使いますので他の用途での使用は避けてください。

さて中身ですが、IDとPropertyの組み合わせで一意のValueを得たいのですね?
DBのNullはC#のNullにマッピングされることもありますが、両者は完全にべつのものです。
DBのNullは値が未定(C#は参照が未定)のことでNullとの演算は全てNullになります。
ですからキーにNullは原則使えません。
IDもPropertyもNull非許容にして、その2つで複合キーにしValueを得るようにしてください。
SELECT分の組み換えなど不要です。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/10/16 18:14

    とりうる値を別マスタで管理するということですね。
    確かにそうすれば"値が設定されていない状態"をnull以外で管理できそうです。
    そのうえで元の話に戻るのですが、値を取得する際に、「0 or 1 で先に検索して、無ければ2で検索」というのを、もう少し効率良くやりたいです。タイトルにも書きましたが、「特定レコードが無ければ"その他"を利用する」みたいなイメージなのですが…

    キャンセル

  • 2018/10/16 18:17

    ORDER BY で並び替えて、TOP 1 を取得すればOKです。

    キャンセル

  • 2018/10/16 18:24

    その通りですね。目からうろこでした。ありがとうございます。
    色々と悩んで難しく考えすぎていたようです。
    分かりにくい説明にお付き合いいただき、ありがとうございました。

    キャンセル

+1

なぜPropertyのような項目が増える度にSELECT文が倍々に増えるのかがよくわかりません。
Propertyのような項目という意味は、条件が増えるということですよね?
例えばAND条件としてのPropertyが増えたのなら、

select Value from Table01 where ID = "001" and Property = true and Property2 = false

のようにすればいいし、OR条件なら追加した and を or にするだけです。
つまり、where文の内容が変わるだけでSELECT文を増やしていく必要はないと思うのですが・・・。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/10/16 17:37

    文章が分かりにくくて申し訳ないのですが、「Propertyのような項目」は設定されている場合とされていない場合があります。必ず設定されているのならPineMatsu様のおっしゃる通りWHERE条件を変えていくだけなのですが、「設定されているものが見つからない場合に設定されていないものを探す」といったことをやりたいです。

    キャンセル

+1

limitの使えるDBMSなら、Propertyが重みを付けられるような値にしてあげれば、1回で取得可能になります。

select Value from Table01 where ID = "001" order by Property limit 1


他のマスタを参照する必要があるなら上記SQLに結合しておけばいい話ですし。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/10/16 18:26

    回答ありがとうございます。その通りですね。
    残念ながら他の回答者様(何度も質問をさせていただいたので…)をベストアンサーとさせていただきましたが、端的で分かりやすい回答ありがとうございました。

    キャンセル

0

なんで、複数の問い合わせ(DBへの)を行わなければいけないのか、よく理解できません。
私でしたら、select Value from Table01 where ID = "001"だけを発行し、その他条件についてはクライアント側のAPにて判断すればいいのでは?と思いますけど。??

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/10/16 17:45

    DBへの問合せを例にしたのが分かりにくかったかもしれません。申し訳ありません。
    AP側でするにしても結果的に「ID="001"の中からまずPropertyがtrue/falseのものを探し、無ければnullのものを使用する」というロジックは変わらないと思います。
    ロジックとして、(DBからでもAP内でも)こういったデータからValueを効率よく取得するやり方が無いかと考えており、そういった趣旨のご質問でした。
    タグの付け方等良く分からず誤解を与えてしまい申し訳ありません。

    キャンセル

  • 2018/10/16 18:02

    良く解らないのですが、DBへ問い合わせを複数回行うということは、クライアントから、そのsqlが何らかの方法で、DBサーバーへ送信されます。
    DBサーバーは、そのSQLを解析し、DBが解釈できる(インデックスを探し、データファイルを見つけ、解析した結果ソートなど、行いDBサーバーのメモリーに蓄えられます。)そうしたデータはまた回線を経由しクライアント側で受け取ることになります。複数回問い合わせるということは、
    たとえば利用する環境にもよるのですが、DBへのCONNECT、DISCONECTが発行されるかも?しれません。これは全体的なプロセスからするとかなりの処理能力が利用されます。なので、SQLにて複数回処理するよりも、1回のSQL発行で、あとはクライアント側で判断するほうが
    結果的にシステムとして軽くなると思います。ということでなぜ、複数回のSQLを発行することを検討しているかが疑問に思いました。

    キャンセル

  • 2018/10/16 18:05

    ご回答いただいておいて申し訳ないのですが、そこで悩んでいるわけではありません。
    つまり、「SQL発行回数が多くなることによる性能劣化が心配」という悩みではなく、「あるデータ群から欲しいデータを取得する(DBからにせよAP内部にせよ)処理が冗長になってしまいそうで心配」という悩みです。
    DBへの問い合わせが増えれば処理が重くなるのは十分承知しております。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.93%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • トップ
  • C#に関する質問
  • マスタからのデータ読込みで、キー項目が設定されていない場合は"その他"のデータを取得したい