如何在使用group by时运行mysql循环

时间:2010-12-13 21:49:22

标签: mysql

我有以下四个表:

成员

agent   |   memberid   |   firstname   |   lastname
===================================================
123     |    444       |  john         |    smith
123     |    555       |  sarah        |    stevens
123     |    777       |   harry       |    tabor

如果代理商引用销售代理商ID,则会员ID对每个客户都是唯一的,与该成员关联的名字和姓氏

选择

id   |   memberid   |   programid
=================================
1    |      444     |     1
2    |      444     |     2
3    |      444     |     3
4    |      555     |     1
5    |      555     |     2
6    |      555     |     3
7    |      777     |     1
8    |      777     |     2
9    |      777     |     3

详细说明了每个成员所做的选择,为简单起见,本例中上面列出的每个成员都选择为programID的1,2和3的一部分。

programID  |   cost   |   type
===================================
  1        |   20.00  |     7
  2        |   30.00  |     8
  3        |   40.00  |     9

此表详细列出了每个唯一programID

的费用和系统类型

comp_levels

level  |   type1   |   type2   |   type3
============================================
   1   |   0.25    |   0.15    |  0.1
   2   |   0.3     |   0.18    |  0.11
   3   |   0.35    |   0.2     |  0.12
   4   |   0.4     |   0.225   |  0.15
   5   |   0.425   |   0.25    |  0.17
   6   |   0.45    |   0.27    |  0.2
   7   |   0.47    |   0.28    |  0.22
   8   |   0.5     |   0.3     |  0.24

此表突出显示每个特定代理的销售佣金结构,基于其级别并使用上述GROUPS中的系统类型。

对于这个例子,我们假设Agent 123处于佣金级别2。

最终,我正在尝试建立一个报告系统,根据销售额,各自的佣金水平以及他们带来的销售类型,详细说明单个代理商和一组代理商的佣金结构。

我当前的sql语句(不满足我的需要)是:

select
    a.memberid,
    a.firstname,
    a.lastname,
    sum(c.cost) as Cost,
CASE
    when c.type = '5' THEN (SUM(c.cost) * d.type1)
    when c.type = '6' THEN (SUM(c.cost) * d.type2)
    when c.type = '7' THEN (SUM(c.cost) * d.type3)
END as Commission
FROM
    members a
left join selections b using(memberid)
left join groups c using(programid)
left join comp_levels d on d.level = '2'
where agent = '123'
GROUP BY a.memberid;

此查询的结果是:

memberid   |  firstname   | lastname   |   Cost   |   Commission
================================================================
   444     |   john       | smith      |   60.00  |   27.00
   555     |   sarah      | stevens    |   60.00  |   27.00
   666     |   harry      | tabor      |   60.00  |   27.00

我面临的问题是结果集正在进行第一次CASE匹配并应用于返回的几行,而实际上它只应用于每一行,然后对结果进行分组。

在上面的例子中,每个特定成员的佣金应该是15.18美元(20美元的30%+ 30美元的18%+ 40美元的11%)但是它采取的是案例1并将30%的佣金用于每个结果( 90美元的30%)。

我玩了几个变种,但我无法弄清楚如何在一个查询中组合我想要做的事情(这个查询只能从一个mysql gui运行,所以使用任何编程语言是不可接受的。

1 个答案:

答案 0 :(得分:1)

我认为主要问题是您在CASE中未正确使用GROUP BY。我认为大多数SQL平台会抱怨你尝试这样的东西,但MySQL只会给你下铺/随机结果并微笑。

无论如何,我认为由于不寻常的架构,你必须使用子查询来获得你想要的东西。像这样的东西

SELECT 
    sq.memberid, sq.firstname, sq.lastname, 
    SUM(sq.cost) AS total_cost, SUM(sq.commission) AS total_commission
FROM 
(
    SELECT 
    m.memberid, m.firstname, m.lastname, g.cost, 
    CASE
        WHEN g.type = '7' THEN (g.cost * cl.type1)
        WHEN g.type = '8' THEN (g.cost * cl.type2)
        WHEN g.type = '9' THEN (g.cost * cl.type3)
    END as commission
    FROM members m
    LEFT JOIN selections s USING(memberid)
    LEFT JOIN groups g USING(programid)
    LEFT JOIN comp_levels cl ON cl.level = '2'
    WHERE m.agent = '123' 
) sq GROUP BY sq.memberid

您可以单独运行子查询来跟踪正在发生的事情。

使用您的数据,它会给出结果

+----------+-----------+----------+------------+------------------+
| memberid | firstname | lastname | total_cost | total_commission |
+----------+-----------+----------+------------+------------------+
|      444 | john      | smith    |      90.00 |           15.800 |
|      555 | sarah     | stevens  |      90.00 |           15.800 |
|      777 | harry     | tabour   |      90.00 |           15.800 |
+----------+-----------+----------+------------+------------------+

注意:由于异常(缺乏)规范化,即将类型(7,8,9)映射到类型字段(type1,type2,type3),这是一个难以解决的问题。此外,我认为您的测试数据描述中可能存在一些拼写错误;即SQL中的类型值,以及查询输出中的总成本和所需结果。