0

我有一个中等复杂的查询要运行,为了这个问题,我在下面做了一些简化。我有 2 张桌子;

TABLE: plan_costs
id,   plan_id,   cost,    special_cost   + more columns....
1     1          23.00    12.00
2     1          25.00    15.00
3     2          5.00     2.00
4     2          45.00    28.00
5     3          35.00    30.00
6     3          65.00    60.00

TABLE: plan_details
plan_id,   group_id,    + more columns....
1          1
2          1
3          2

我需要的是最便宜的计划列表,介于 2 个值之间(在本例中为 5 和 30),但每组只有一个计划。当我运行下面的计划时,我每组得到一个计划,但它并不总是最便宜的。注意:有一个 case 条件,如果它不为 0,则优先使用 special_cost 而不是 cost。有什么想法吗?

SELECT p1.id,
       p2.plan_id,
       p1.cost,
       p1.special_cost CASE
                           WHEN p1.special_cost = 0 THEN MIN(p1.cost)
                           ELSE MIN(p1.special_cost)
                       END AS cost_order,
FROM plan_costs AS p1
LEFT JOIN plan_details AS p2 ON (p2.plan_id = p1.plan_id)
WHERE CASE
          WHEN p1.special_cost = 0 THEN p1.cost >= 5
          ELSE p1.special_cost >= 5
      END
  AND CASE
          WHEN p1.special_cost = 0 THEN p1.cost <= 30
          ELSE p1.special_cost <= 30
      END
GROUP BY p2.group_id
ORDER BY CASE
             WHEN p1.special_cost = 0 THEN p1.cost
             ELSE p1.special_cost
         END ASC

编辑:添加了我需要的最终结果

要求的结果:

id,   plan_id,   cost,    special_cost
1     1          23.00    12.00
5     3          35.00    30.00
4

1 回答 1

1

试试这个查询

SELECT 
   a.group_id, 
   pc.plan_id,
   a.minCost
FROM
   (SELECT 
      pd.group_id,
      min(if(pc.special_cost = 0, pc.cost, pc.special_cost)) as minCost 
   FROM
      plan_costs pc
   INNER JOIN
      plan_details pd
   ON 
      pd.plan_id = pc.plan_id
   GROUP BY 
      pd.group_id) a
INNER JOIN
   plan_details pd
ON   
   pd.group_id = a.group_id
INNER JOIN
   plan_costs pc
ON
   pc.plan_id = a.plan_id AND 
   if(pc.special_cost = 0, pc.cost, pc.special_cost) = a.minCost

MySQL 扩展了 GROUP BY 的使用,以便选择列表可以引用未在 GROUP BY 子句中命名的非聚合列。服务器可以自由地从每个组中选择任何值,所以在我们的例子中plan_id是不同的,所以我们不能利用这个特性,所以我们必须进行额外的连接来获得想要的结果......

希望这可以帮助...

于 2013-04-12T06:29:23.320 回答