MySQL多级嵌套CASE那么ELSE优先吗?

时间:2016-06-02 08:59:15

标签: mysql

我试图围绕这个我遇到过的小问题。

我正在加入多个包含车辆信息的表格(包括品牌,型号,类型,子类型,零件编号和零件标题),以便通过我的"标题覆盖"对于某些车辆品牌,型号,类型或子类型,可能(或可能不)包含某些车辆部件在某些情况下会覆盖其标题的条目的表格。

如同在,考虑使用标准油用于所有宝马汽车,然后对于宝马M5,有一个例外,用另一种优质油覆盖标准油。或者说所有汽车都使用标准油,除非本表另有说明。优先级列在清单中:

  • 特定型号(最高优先级)
  • 具体制作(第二高优先级)
  • 子类型(第三高优先级)

因此覆盖表(" ov")看起来像这样:

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适用于摩托车,type_id = 3适用于汽车,例如

**如果make_id,subtype_id或model_id为= 0,则表示覆盖应适用于所有品牌,子类型和模型,除非值<>指定了0。

对于part_id = 33,我只需要在结果中显示一次,而不是多次,具体取决于在应用程序中查询的模型以及它适合的位置"矩阵"。 / p>

因此,如果我在Yamaha R6 2015版上运行此查询,并且需要为该模型提取该part_id = 33的代码/标题," model_id"列优先于所有其他列,因此我将忽略所有其他列并显示记录#5的标题。

如果我选择另一辆Yamaha Street自行车,我获得的最高优先级匹配将是#4记录(因为它同时定义了make_id和subtype_id)。

或者,如果我选择一个随机的Dirtbike,我将在#3记录(在subtype_id上​​)获得匹配,以便显示代码/标题。

然后,如果我选择任何雅马哈自行车,我将在#2记录上获得一场比赛(在make_id上​​)。

最后,如果没有指定这些,我只选择一个随机的自行车,它将显示#1记录,因为这将匹配type_id(bikes = 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)

我在这个查询中获得的是适用于所列特定模型的所有部分,因此,如果我为特定模型运行它,如Yamaha R6 2015,我将获得#1,2和5的记录来起来。但是我只需要记录#5,如上所述,按照重要性和优先级的顺序显示。

如果我执行GROUP BY part_id或类似的东西,那么我只会显示一条记录,但就最高优先级而言,它不一定是正确的记录。

我错过了什么?

或者我如何能够对整个重要性/优先级进行级联检查,以便查看其他连接表中的所有部分记录并根据此覆盖(" ov")表对其进行过滤只根据某种瀑布或级联规则吐出最高优先级的记录?

不确定如何写,或者甚至可能。

或者如果我必须将它作为一个经常存储的程序来运行,那也很好。

谢谢!

1 个答案:

答案 0 :(得分: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

然后,您可以更改优先顺序" OV"你想要在coalesce()中的版本。因此,如果Model的优先级高于make:

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

无论哪个领域都不是第一次胜利。