1

下面是我的 brand_of_items 表的架构。为简单起见,此处显示为两列:id(主要和 AI)、符号(varchar 50,唯一)

Table - brand_of_items
id   symbol
0    a
1    b
2    c
..   ..
10   j

下面是我的 items_of_brand 的架构。

Table - mainIndexQuantity
id  brand_of_items_id   vol  item_type  salefinalizeddate
0         1              5      0       2005-5-11
1         1              6      0       2004-5-11
2         1              7      0       2011-5-11
3         1              8      0       2011-5-12
4         1              9      0       2011-5-12
5         1              10     0       2011-5-11
6         1              5      1       2012-5-11
7         1              6      1       2012-5-11
8         1              7      1       2011-5-11
9         1              8      1       2010-5-12
10        1              9      1       2012-5-12
11        1              10     1       2005-5-12

mainIndexQuantity 表brand_of_items_id 列是指向brand_of_items (id) 的外键。mainIndexQuantity 表 item_type 列不是外键,它应该是。

这两种商品类型是:0 = 零售和 1 = 批发

我想计算每个 each_brand_of_items 表条目的商品类型(零售与批发)的比率。目标是查看某个品牌的商品是在零售还是批发中销售更多。


** 添加复杂性:我想在 mainIndexQuantity 表中添加一个日期列,并想找出RetailVolume 和 WholesaleVolume 总和的差异,并按 salefinalizeddate 字段对结果进行分组。

这是为了帮助确定哪些商品在哪个季节销售得更多,RetailVolume 和 WholeSaleVolume 总和的(增量)差异将有助于选择最关注的商品。

4

1 回答 1

5

试试这个:

SELECT 
  b.id,
  b.symbol,
  IFNULL(SUM(m.item_type = 1), 0) / (COUNT(*) * 1.0) AS wholesaleRatio,
  IFNULL(SUM(m.item_type = 0), 0) / (COUNT(*) * 1.0) AS RetailRatio
FROM brand_of_items b
LEFT JOIN mainIndexQuantity m ON b.id = m.brand_of_items_id
GROUP BY b.id, 
         b.symbol;

SQL 小提琴演示

这会给你:

| ID | SYMBOL | WHOLESALERATIO | RETAILRATIO |
----------------------------------------------
|  0 |      a |              0 |           0 |
|  1 |      b |            0.5 |         0.5 |
|  2 |      c |              0 |           0 |
| 10 |      j |              0 |           0 |

假如说:

  • wholesaleRatio是 Whole sale 类型的项目的计数到所有项目的计数。
  • RetailRatio是类型项目retail的计数到所有项目的计数。

如果这个配给是vol列的总和到总数vol,你可以这样做:

SELECT 
  b.id,
  b.symbol,
  SUM(CASE WHEN m.item_type = 1 THEN m.vol ELSE 0 END) / SUM(m.vol) AS wholesaleRatio,
  SUM(CASE WHEN m.item_type = 0 THEN m.vol ELSE 0 END) / SUM(m.vol) AS RetailRatio
FROM brand_of_items b
LEFT JOIN mainIndexQuantity m ON b.id = m.brand_of_items_id
GROUP BY b.id, 
         b.symbol;

注意:

  • 我使用LEFT JOIN, 以便您在结果集中获得不匹配的行,即MainIndexQuantity表中没有条目的那些品牌项目。如果您不想包含它们,请INNER JOIN改用。
  • 正如@JW 所指出的,乘以1.0得到小数位数。

更新 1

要包括Total Volume,Retail Volume SumWholesale Volume sum尝试以下操作:

SELECT 
  b.id,
  b.symbol,
  IFNULL(SUM(m.item_type = 1), 0) * 1.0 / COUNT(*)     AS wholesaleRatio,
  IFNULL(SUM(m.item_type = 0), 0) * 1.0 / COUNT(*)     AS RetailRatio,
  IFNULL(SUM(m.vol), 0)                                AS 'Total Volume',
  SUM(CASE WHEN m.item_type = 1 THEN m.vol ELSE 0 END) AS 'Retail Volume sum',
  SUM(CASE WHEN m.item_type = 1 THEN m.vol ELSE 0 END) AS 'Wholesale Volume sum'
FROM brand_of_items b
LEFT JOIN mainIndexQuantity m ON b.id = m.brand_of_items_id
GROUP BY b.id, 
         b.symbol;

更新了 SQL Fiddle 演示

这会给你:

| ID | SYMBOL | WHOLESALERATIO | RETAILRATIO | TOTAL VOLUME | RETAIL VOLUME SUM | WHOLESALE VOLUME SUM |
--------------------------------------------------------------------------------------------------------
|  0 |      a |              0 |           0 |            0 |                 0 |                    0 |
|  1 |      b |            0.5 |         0.5 |           90 |                45 |                   45 |
|  2 |      c |              0 |           0 |            0 |                 0 |                    0 |
| 10 |      j |              0 |           0 |            0 |                 0 |                    0 |

如果您想按这些总计和总和对结果集进行排序,请将此查询放在子查询中,然后您可以这样做:

SELECT *
FROM
(
   SELECT 
      b.id,
      b.symbol,
      IFNULL(SUM(m.item_type = 1), 0) * 1.0 / COUNT(*)     AS wholesaleRatio,
      IFNULL(SUM(m.item_type = 0), 0) * 1.0 / COUNT(*)     AS RetailRatio,
      IFNULL(SUM(m.vol), 0)                                AS TotalVolume,
      SUM(CASE WHEN m.item_type = 1 THEN m.vol ELSE 0 END) AS RetailVolumeSum,
      SUM(CASE WHEN m.item_type = 1 THEN m.vol ELSE 0 END) AS WholesaleVolumeSum
    FROM brand_of_items b
    LEFT JOIN mainIndexQuantity m ON b.id = m.brand_of_items_id
    GROUP BY b.id, 
             b.symbol
) AS sub
ORDER BY RetailVolumeSum    DESC, 
         WholesaleVolumeSum DESC;

但是您的最后一个要求并不清楚,您是在寻找那些具有最高 retio/wholesale ratis 和 volumns 的商品品牌,还是选择其中价值最高的商品?

对于后一个:

SELECT *
FROM
(
   SELECT 
      b.id,
      b.symbol,
      IFNULL(SUM(m.item_type = 1), 0) * 1.0 / COUNT(*)     AS wholesaleRatio,
      IFNULL(SUM(m.item_type = 0), 0) * 1.0 / COUNT(*)     AS RetailRatio,
      IFNULL(SUM(m.vol), 0)                                AS TotalVolume,
      SUM(CASE WHEN m.item_type = 1 THEN m.vol ELSE 0 END) AS RetailVolumeSum,
      SUM(CASE WHEN m.item_type = 1 THEN m.vol ELSE 0 END) AS WholesaleVolumeSum
    FROM brand_of_items b
    LEFT JOIN mainIndexQuantity m ON b.id = m.brand_of_items_id
    GROUP BY b.id, 
             b.symbol
) AS sub
ORDER BY RetailVolumeSum    DESC, 
         WholesaleVolumeSum DESC,
         TotalVolume        DESC
LIMIT 1;

更新 2

要获得总销量最高的品牌,您可以这样做:

SELECT 
  b.id,
  b.symbol,
  IFNULL(SUM(m.item_type = 1), 0) * 1.0 / COUNT(*)     AS wholesaleRatio,
  IFNULL(SUM(m.item_type = 0), 0) * 1.0 / COUNT(*)     AS RetailRatio,
  IFNULL(SUM(m.vol), 0)                                AS TotalVolume,
  SUM(CASE WHEN m.item_type = 1 THEN m.vol ELSE 0 END) AS RetailVolumeSum,
  SUM(CASE WHEN m.item_type = 1 THEN m.vol ELSE 0 END) AS WholesaleVolumeSum
FROM brand_of_items b
LEFT JOIN mainIndexQuantity m ON b.id = m.brand_of_items_id
GROUP BY b.id, 
         b.symbol
HAVING SUM(m.vol) = (SELECT MAX(TotalVolume)
                     FROM
                     (
                       SELECT brand_of_items_id, SUM(vol) AS TotalVolume
                       FROM mainIndexQuantity
                       GROUP BY brand_of_items_id
                     ) t);

像这样

注意:

  • 这将为您提供总销量最高的品牌,如果您正在寻找比例最高的品牌,您必须替换having子句以获得比例的最大值而不是总销量的最大值。

  • 这将为您提供总体积最高的项目,因此您可能希望拥有多个项目,以防有多个项目的总体积最高,就像在这个更新的小提琴演示中一样。在这种情况下,要仅获取一个,您必须使用LIMITto 仅返回一个。

于 2013-02-06T02:40:45.180 回答