0

我需要一些帮助来构建查询。

这是我需要的:

我有一个名为data的表:

   ID| PRODUCT | VALUE |COUNTRY|  DEVICE | SYSTEM 
-----+---------+-------+-------+---------+--------
48   |    p1   |  0.4  |   US  |  dev1   | system1   
47   |    p2   |  0.67 |   IT  |  dev2   | system2   
46   |    p3   |  1.2  |   GB  |  dev3   | system3          
45   |    p1   |  0.9  |   ES  |  dev4   | system4   
44   |    p1   |  0.6  |   ES  |  dev4   | system1 

我需要展示哪些产品产生了最多的收入,以及哪个国家、设备和系统贡献最大。

**例如:我从表中得到的结果是:

 PRODUCT | TOTAL COST |COUNTRY|  DEVICE | SYSTEM 
  -------+------------+-------+---------+--------
    p1   |     1.9    |   ES  |  dev4   | system1   
    p2   |     0.67   |   IT  |  dev2   | system2   
    p3   |     1.2    |   GB  |  dev3   | system3 

排名靠前的国家是 ES,因为 ES 贡献了 0.9 + 0.6 = 1.5 > 0.4(美国的贡献)。

顶级设备和顶级系统的逻辑相同。**

我想对于总收入和产品来说,这样的事情会做:

SELECT SUM(value) as total_revenue,product FROM data GROUP BY product

但是如何添加国家、设备和系统?

这在单个查询中是否可行,如果不是最好的方法(性能方面)是什么?

非常感谢您的帮助。

编辑 我编辑了示例表以更好地解释。

4

3 回答 3

1

你是对的......这不仅仅是一个简单的查询......而是将 3 个查询包含在一个结果中。

我已经在SQL Fiddle 上发布了我的示例...

第一个查询——最里面。您需要根据每个产品/国家/地区获得所有收入,并按产品对其进行排序,然后按总收入递减,以使每个产品的收入最高。

下一个查询(我已经实现了使用 MySQL @variable 的地方)。由于第一个结果订单已经按照产品和收入排名的顺序排列,所以每当产品从“@LastProd”是什么变化时,我都会将排名设置为 1……这将为产品 1 创建 ES = Rank #1,然后 US = 产品 1 的排名 #2,然后继续其他“产品”。

最后的最外层查询重新连接回原始数据表,但会获取包含相关产品销售的所有设备和系统的列表,但仅限于产品排名为 #1 的位置。

select
      pqRank.product,
      pqRank.country,
      pqRank.revenue,
      group_concat( distinct d2.device ) as PartDevices,
      group_concat( distinct d2.system ) as PartSystems
   from
      ( select
              pq.product,
              pq.country,
              pq.revenue,
              @RevenueRank := if( @LastProd = pq.product, @RevenueRank +1, 1 ) as ProdRank,
              @LastProd := pq.product
           from
              ( select 
                      d.product,
                      d.country,
                      sum( d.value ) as Revenue
                   from
                      data d
                   group by 
                      d.product,
                      d.country
                   order by
                      d.product,
                      Revenue desc ) pq,
              ( select @RevenueRank := 0,
                       @LastProd := ' ') as sqlvars
      ) pqRank
         JOIN data d2
            on pqRank.product = d2.product
           and pqRank.country = d2.country
   where
      pqRank.ProdRank = 1
   group by
      pqRank.product,
      pqRank.country
于 2012-11-12T01:45:59.093 回答
1

在单独的查询中执行此操作:

SELECT   product,
         SUM(value) AS amount
FROM     data
GROUP BY country    -- change to device, system, etc. as required
ORDER BY amount DESC
LIMIT    1
于 2012-11-11T23:29:09.450 回答
0

你可以那样做

CREATE TABLE data 
(
id int auto_increment primary key, 
product varchar(20), 
country varchar(4),
device varchar(20),
system varchar(20),
value decimal(5,2)
);

INSERT INTO data (product, country, device, system, value)
VALUES 
('p1', 'US', 'dev1', 'system1', 0.4), 
('p2', 'IT', 'dev2', 'system2', 0.67), 
('p1', 'IT', 'dev1', 'system2', 0.23);

select 'p' as grouping_type, product, sum(value) as sumval
from data
group by product
union all
select 'c' as grouping_type, country, sum(value) as sumval
from data
group by country
union all
select 'd' as grouping_type, device, sum(value) as sumval
from data
group by device
union all
select 's' as grouping_type, system, sum(value) as sumval
from data
group by system
order by grouping_type, sumval

它很难看,我不会使用它,但它应该可以工作。

于 2012-11-11T23:26:23.440 回答