2016-06-02 14 views
0

私はこの小さな問題に取り組んでいます。MySQLマルチレベルネストされた場合優先度が高い場合?

車の情報(メイク、モデル、タイプ、サブタイプ、部品番号、部品のタイトルなど)を含む複数のテーブルに参加して、「タイトルオーバーライド」テーブルを通過することができます。特定の車両メーカー、モデル、タイプまたはサブタイプについて、車両部品のタイトルが上書きされることがあります。

同様に、すべてのBMW車に標準オイルを使用し、BMW M5では標準オイルを別のプレミアムオイルで上書きするという例外があります。あるいは、この表で特に指定されていない限り、すべての車に標準的なオイルが使用されているとします。そして、優先順位リストをダウン:

  • 特定のモデル(最優先)
  • 特定のmake(第二優先順位が最も高い)(第三最高の優先度)

だから、オーバーライド・テーブル

  • サブタイプ( TYPE_ID = 3のために、自動車用で、オートバイのためである

    id | type_id | make_id | subtype_id | model_id | part_id | part_override 
    1 | 2  | 0 | 0  | 0  | 33 | Global-Replacement-Oil 
    2 | 2  | 1 | 0  | 0  | 33 | Yamaha-Premium-Oil 
    3 | 2  | 0 | 2  | 0  | 33 | Global-Dirtbike-Oil 
    4 | 2  | 1 | 4  | 0  | 33 | Yamaha-Streetbike-Oil 
    5 | 2  | 0 | 0  | 199 | 33 | Yamaha-R6-2015-Oil 
    

    ** TYPE_ID = 2: "OV")は次のようになります例

    ** make_id、subtype_idまたはmodel_idが0の場合、値<> 0が指定されていない限り、すべてのメイク、サブタイプおよびモデルにオーバーライドを適用する必要があります。

    そのpart_id = 33の場合、アプリケーションで照会されるモデルとその「マトリックス」に収まる場所によっては、結果に複数回ではなく1回だけ表示する必要があります。

    ヤマハR6 2015版でこのクエリを実行していて、そのモデルのpart_id = 33のコード/タイトルを取得する必要がある場合、「model_id」列は他のすべての列よりも優先順位が高いため、他のすべてのものを無視して、レコード#5のタイトルを表示します。

    私が別のヤマハストリートバイクを選んだ場合、最高の優先順位はレコード#4です(make_idとsubtype_idの両方が定義されているため)。

    ランダムDirtbikeを選んだ場合、レコード#3(subtype_id)に一致するので、代わりにコード/タイトルが表示されます。

    ヤマハの自転車を選ぶと、レコード#2(make_id)にマッチします。

    最後に、それらのどれも指定されておらず、ただランダムなバイクを選んだ場合は、代わりにレコード#1が表示されます。これはtype_idだけで一致します(バイク= 2)。

    これは私がこれまでに(またはその一部)を持つクエリです:私はこのクエリを取得しています何

    SELECT DISTINCT 
    CASE 
        WHEN p.part_id = '72' AND ov.part_override != "" AND ov.type_id = p.type_id AND 
        (CASE 
         WHEN ov.model_id IS NOT NULL 
         THEN ov.model_id = "$MODEL_ID" 
         ELSE 
         CASE 
          WHEN ov.make_id != 0 
          THEN ov.make_id = m.make_id 
          ELSE 
          CASE 
           WHEN ov.subtype_id != 0 
           THEN ov.subtype_id = st.subtype_id 
           ELSE 1 
          END 
         END 
         END) 
        THEN ov.part_override 
        ELSE p.part_number 
    END part_number, 
    ov.make_id, 
    .... 
    FROM parts p ON ... 
    INNER JOIN makes m ON p.make_id = m.make_id 
    INNER JOIN ... 
    (just joining a bunch of other separate tables that contain all types, 
    subtypes, models and so on, respectively - irrelevant for the logic above) 
    

    が記載されている特定のモデルに適用されるすべての部品であるので、私は実行する場合ヤマハR6 2015のような特定のモデルのためには、レコード#1,2と5が出てくるよ。しかし、私は上記のように、重要度と優先順位の順に表示するには、レコード#5が必要です。

    GROUP BYのpart_idなどを実行すると、1つのレコードしか表示されませんが、必ずしも最高の優先度で表示されるわけではありません。

    私には何が欠けていますか?

    他の結合テーブル内のすべてのパーツレコードを調べて、このオーバーライド( "ov")テーブルに基づいてフィルタリングしている間、この重要度/優先度チェックをすべてカスケードして何らかの滝やカスケードルールに基づいて、最も優先順位の高いレコードですか?

    これを書く方法や、それが可能なのかどうかはわかりません。

    あるいは、私はそれを並べ替えの定期的なストアドプロシージャとして実行する必要がある場合、それも良いです。

    ありがとうございます!

  • 答えて

    1

    他のテーブル結合や実際のテーブル名を正確に見ることなく、オーバーライドテーブルへの複数の左結合が必要な場合は、最初のFOUND値に基づいてCOALESCEを引き出します。何かのように..

    select 
         ... 
         coalesce(P_OV.part_override, M_OV.part_override, 
          MOD_OV.part_override, P.PartName) as FinalPartName 
        from 
         Parts P 
         left join PartsOverride P_OV 
          on p.id = P_OV.part_id 
         join make m 
          on p.make_id = m.make_id 
          left join PartsOverride M_OV 
           on m.make_id = M_OV.make_id 
         join model mo 
          on p.model_id = mo.model_id 
          left join PartsOverride MOD_OV 
           on m.make_id = MOD_OV.make_id 
    

    次に、coalesce()内の "OV"バージョンの優先順位を変更することができます。したがって、Modelがmakeよりも優先度が高い場合:

    coalesce(MOD_OV.part_override, M_OV.part_override, 
         P_OV.part_override, P.PartName) as FinalPartName 
    

    いずれのフィールドもNOT NULL FIRST WINSです。

    +0

    ブリリアント!複数の左の結合+合体...それは自分のことを決して考えなかったでしょう。ありがとうございます! –

    関連する問題