选择... CASE WHEN ...按别名排序

时间:2014-08-05 17:34:33

标签: mysql case

以下是我的表格:

表程序prg

  • prg_id
  • ln1_id
  • pmt_id
  • prg_commission
  • dep_id

Table COMMISSION com

  • com_id
  • pmt_id
  • ln1_id
  • dep_id
  • com_commission

表PROMOTEUR pmt

  • pmt_id
  • pmt_txcommission

我需要获得表格程序的“佣金”

但是当它为null或为空(prg.commission)时,我需要从表“Commission”中获取“佣金”值(com.commission - 来自两个表的ln1_id,pmt_id和dep_id匹配)。

如果没有结果匹配(没有结果表COMMISSION,其中com.ln1_id = prg.ln1_id和com.pmt_id = prg.ln1_id和com.dep_id = prg.dep_id)我需要获得PROMOTEUR的“佣金” (pmt.commission)

我真的不知道如何在Sql中做到这一点...在PHP条件下会更容易但我必须在MySQL上做,因为在为我的每个程序获得“Commission”的良好价值后,我需要通过ASC对它们进行订购......

我不确定我是否容易理解(英语不是我的母语)。这是我尝试过的一个例子(不成功的遗憾),因为我的条件太多了!

SELECT prg.commision AS commission, pmt.commission AS commission, com.commission AS commission
FROM (((PROGRAMME prg
LEFT JOIN LOINIVEAU1 ln1 ON ln1.ln1_id = prg.ln1_id)
LEFT JOIN PROMOTEUR pmt ON pmt.pmt_id = prg.pmt_id)
LEFT JOIN COMMISSION com ON com.pmt_id = pmt.pmt_id)
WHERE 
    CASE prg.comission != null 
      THEN prg.comission 
      ELSE CASE com.commission != null 
             THEN com.commission 
             ELSE pmt.commission 
      THEN pmt.commission 
ORDER BY commission ASC

1 个答案:

答案 0 :(得分:3)

这就是你想要的:

   SELECT COALESCE(prg.commission, com.commission, pmt.commission) resolved_commission
     FROM PROGRAMME prg
LEFT JOIN COMMISSION com 
       ON com.pmt_id = prg.pmt_id
      AND com.ln1_id = prg.ln1_id
      AND com.dep_id = prg.dep_id
LEFT JOIN PROMOTEUR pmt 
       ON pmt.pmt_id = prg.pmt_id
 ORDER BY resolved_commission

我已采取以下步骤:

  • LEFT JOIN移至LOINIVEAU1,因为这似乎没有必要
  • 更新了其他LEFT JOIN条件,以反映您的说明中的内容
  • 使用COALESCE从逗号分隔列返回第一个not null值。这将替换您在CASE子句中错误放置的WHERE语句。
  • 删除了不必要的括号。

作为另一个指针..从不使用!= NULL使用IS NOT NULL代替..因为事实证明我在我的解决方案中不需要这个。

<强>更新

了解更多信息:

   SELECT CASE 
            WHEN prg.commission > 0
               AND prg.commissionstart >= CURDATE()
               AND prg.commissionend < CURDATE() + INTERVAL 1 DAY
              THEN prg.commission
            WHEN com.commission > 0
              THEN com.commission
            WHEN pmt.commission > 0
              THEN pmt.commission
            ELSE 0 /* Whatever you want, probably 0 */
          END resolved_commission
     FROM PROGRAMME prg
     JOIN PROGRAMME_DEPARTMENT prg_dep
       ON prg_dep.prg_id = prg.id /* Guessing the JOIN here */
LEFT JOIN COMMISSION com 
       ON com.pmt_id = prg.pmt_id
      AND com.ln1_id = prg.ln1_id
      AND com.dep_id = prg_dep.dep_id
LEFT JOIN PROMOTEUR pmt 
       ON pmt.pmt_id = prg.pmt_id
      AND pmt.commissionstart >= CURDATE()
      AND pmt.commissionend < CURDATE() + INTERVAL 1 DAY
 ORDER BY resolved_commission

应该让你更近一点..

为了更加清晰,您可以将x > 0替换为x IS NOT NULL and x > 0中的CASE

我还要认真考虑将COMMISSION表中的所有佣金放在开头和结尾,并将prg.commission*pmt.commission*替换为通过此表的中间人的链接..这您可以摆脱所有0值并使用LEFT JOIN COALESCE来获取resolve_commission。

表现TWEAKS

使用EXPLAIN [EXTENDED] ...查看查询的执行方式,并在每个表格中使用以下列的复合索引组合:

  • PROGRAMME :( [id,],pmt_id,ln1_id,Commission,commissionstart,commissionend)
  • PROGRAMME_DEPARTMENT :( pmt_id,ln1_id,dep_id)
  • COMMISSION :( pmt_id,ln1_id,dep_id,佣金)
  • PROMOTEUR :( pmt_id,Commission,commissionstart,commissionend)