根据group by划分列值(数字)

时间:2016-02-07 09:52:07

标签: php mysql

首先,我对MySQL的态度不是很好,无论我有什么经验,我都会用它来进行这个查询

在我的查询中,主要问题是

        left join subdealers as subdealer
            ON 
                (
                    employees.Salesman1Number = subdealer.employee_number 
                    OR employees.Salesman2Number = subdealer.employee_number
                    OR employees.Salesman3Number = subdealer.employee_number
                )

我正在尝试按FrontGross分组BackGrosssubdealer.group_name等问题Saleman1Number& Salesman2Number可能属于同一个group_name,在下面的查询中,它会将它们视为两个不同的销售人员,而我希望它们在Salesman1NumberSaleman2NumberSalesman2Numbersubdealer.group_name属于同一个Salesman1Number

例如:group_name属于Salesman2Number舰队,group_name也属于舰队

他们都出售了一辆汽车。现在他们都对他们卖出的东西有一半的信用,而且这个信用归Salesman1Number舰队为一半,一半来自Salesman2Number,另一半来自group_name

目前我写的查询并不是根据Salesman1Number将它们分成两半,而是从Salesman2Number计算为一个  和一个来自SELECT count(core_leads.core_id) as leads, count(new.id) as new, count(used.id) as used, IFNULL(SUM(profit.FrontGross) + SUM(finance.HoldbackAmount), 0) as FrontGross, IFNULL(SUM(profit.BackGross) + SUM(profit.FinanceReserve), 0) as BackGross, IFNULL(SUM(profit.TotalProfit), 0) as TotalProfit, IFNULL(SUM(finance.HoldbackAmount), 0) as HoldbackAmount, IFNULL(SUM(finance.Holdcheck), 0) as Holdcheck, IFNULL(subdealer.group_name, 'Others') as group_name from core_leads inner join ( select * from closed_deals right join ( select ContractDate, id as infoId, closed_deal_id from closed_deal_infos ) as info ON closed_deals.id = info.closed_deal_id AND DATE(info.ContractDate) BETWEEN '2014-01-01' AND '2017-01-01' ) as closed ON core_leads.core_id = closed.core_lead_id AND core_leads.type != 'Unwind' AND core_leads.type != 'Canceled' left join closed_vehicles as used ON closed.id = used.closed_deal_id AND used.NewUsed = 'U' left join closed_vehicles as new ON closed.id = new.closed_deal_id AND new.NewUsed = 'N' left join closed_dealer_employees as employees ON closed.id = employees.closed_deal_id left join subdealers as subdealer ON ( employees.Salesman1Number = subdealer.employee_number OR employees.Salesman2Number = subdealer.employee_number OR employees.Salesman3Number = subdealer.employee_number ) AND ( subdealer.group_name = 'Fleet' OR subdealer.group_name = 'Internet' OR subdealer.group_name = 'Sales' ) left join closed_profit as profit ON closed.id = profit.closed_deal_id left join closed_finance as finance ON closed.id = finance.closed_deal_id group by subdealer.group_name

dept

这导致了这个

Database query result

虽然在Fleet leads列名称38应该是40而不是group_name,因为它计算的是两个属于同一{{1}}的不同推销员2

如果我不够清楚,请告诉我

1 个答案:

答案 0 :(得分:1)

为简化您的示例,我将只使用两个表。

人:

| personId | groupId |
|----------|---------|
|        1 |       1 |
|        2 |       2 |
|        3 |       2 |
|        4 |       3 |
|        5 |       4 |
|        6 |       5 |

活动:

| actId | person1Id | person2Id | person3Id | actValue |
|-------|-----------|-----------|-----------|----------|
|     1 |         1 |         2 |         3 |        1 |
|     2 |         1 |         2 |         4 |       10 |
|     3 |         5 |    (null) |    (null) |      100 |

符合您问题的查询将是:

select 
  p.groupId, count(a.actId) numActs, sum(a.actValue) sumVals, group_concat(a.actId) as acts
from activities a
left join persons p on (
  a.person1Id = p.personId or
  a.person2Id = p.personId or
  a.person3Id = p.personId
)
group by p.groupId;

结果:

| groupId | numActs | sumVals |  acts |
|---------|---------|---------|-------|
|       1 |       2 |      11 |   1,2 |
|       2 |       3 |      12 | 1,2,1 |
|       3 |       1 |      10 |     2 |
|       4 |       1 |     100 |     3 |

对于 groupId = 2 的群组,我们计算了三项活动(1,2,1)。 actId = 1 的活动会被计算两次,因为同一组中有两个人。为了防止这种情况,我们可以定义如果person1来自同一组,则不应计算person2的行(应该被过滤掉)。如果person1或person2来自同一组,则不应计算person3的行。这可以在具有相关选择的WHERE子句中完成:

select 
  p.groupId, count(a.actId) numActs, sum(a.actValue) sumVals, group_concat(a.actId) as acts
from activities a
left join persons p on (
  a.person1Id = p.personId or
  a.person2Id = p.personId or
  a.person3Id = p.personId
)
where (p.personId = a.person1Id
  ) or (
    p.personId = a.person2Id and
    p.groupId not in (select groupId from persons where personId = a.person1Id)
  ) or (
    p.personId = a.person3Id and
    p.groupId not in (select groupId from persons where personId in (a.person1Id, a.person2Id))
  )
group by p.groupId;

结果:

| groupId | numActs | sumVals | acts |
|---------|---------|---------|------|
|       1 |       2 |      11 |  1,2 |
|       2 |       2 |      11 |  1,2 |
|       3 |       1 |      10 |    2 |
|       4 |       1 |     100 |    3 |

http://sqlfiddle.com/#!9/604a5/1

注意:如果可能 - 您应该考虑规范化表格。