2011-08-02 54 views
0

女士们,先生们,MySQL两列动态交叉表

我在MySQL 5.1中遇到以下问题。这是我的桌子。

Sale | Store | Product | Discount 
--------------------------------- 
1 | 1 | B  | Yes 
2 | 1 | B  | Yes 
3 | 1 | B  | No 
4 | 1 | D  | Yes 
5 | 1 | A  | No 
6 | 2 | A  | No 
7 | 3 | B  | No 
8 | 3 | B  | No 
9 | 1 | D  | Yes 
10 | 2 | A  | No 

现在,这当然是一个非常不方便的方式来组织数据,但这是该数据如何恰巧进来(并会继续进来)。

我需要能够抛出一个完全任意的产品类型列表(如果您愿意,用逗号分隔);比方说A,B,C。最后,我需要一个商店卖什么东西的清单。这是一个中间结果,以便于理解。

Store | Product | Sales | Discounts 
----------------------------------- 
    1 | A  | 1 | 0 
    1 | B  | 3 | 2 
    1 | C  | 0 | 0 
    2 | A  | 2 | 0 
    2 | B  | 0 | 0 
    2 | C  | 0 | 0 
    3 | A  | 0 | 0 
    3 | B  | 2 | 0 
    3 | C  | 0 | 0 

我需要什么,到底,是这样的:

Store | Product types sold | Discounts given on product types: 
------------------------------------------------------------- 
    1 |   2   |  1 
    2 |   1   |  0 
    3 |   1   |  0 

第三列说,有多少卖(和查询)产品类型分别给予至少一个折扣。我试过了各种各样的动态交叉表生成查询(是的,我已经看过全部),但是我没有足够的精神状态RAM来一次性将所有东​​西都包裹在头上。你如何以最有效的方式来处理这个问题?临时表格/存储过程等都可以,粗略的想法概要非常受欢迎。谢谢!

回答

3

您可以将数据分组的存储和产品生产的中间结果:

mysql> SELECT Store, Product, 
COUNT(1) AS Sales, 
SUM(IF(Discount='Yes', 1, 0)) AS Discounts 
FROM input 
WHERE Product IN ('A', 'B', 'C', 'D') 
GROUP BY Store, Product 
+-------+---------+-------+-----------+ 
| Store | Product | Sales | Discounts | 
+-------+---------+-------+-----------+ 
|  1 | A  |  1 |   0 | 
|  1 | B  |  3 |   2 | 
|  1 | D  |  2 |   2 | 
|  2 | A  |  2 |   0 | 
|  3 | B  |  2 |   0 | 
+-------+---------+-------+-----------+ 
5 rows in set (0.00 sec) 

然后您可以将这个结果只是由商店将它转化成你的最终结果:

mysql> SELECT Store, 
COUNT(1) AS `Product types sold`, 
SUM(Discounts) AS `Discounts given on product types` 
FROM (
SELECT Store, Product, 
COUNT(1) AS Sales, 
SUM(IF(Discount='Yes', 1, 0)) AS Discounts 
FROM input 
WHERE Product IN ('A', 'B', 'C', 'D') 
GROUP BY Store, Product 
) AS intermediate 
GROUP BY Store 
+-------+--------------------+----------------------------------+ 
| Store | Product types sold | Discounts given on product types | 
+-------+--------------------+----------------------------------+ 
|  1 |     3 |        4 | 
|  2 |     1 |        0 | 
|  3 |     1 |        0 | 
+-------+--------------------+----------------------------------+ 
3 rows in set (0.00 sec) 

请注意,第一个查询是第二个查询的子查询。

+0

此时它计算所有折扣,而不是“产品折扣类型'(仅在3种产品类型中返回4折)。 – Inca

+0

是的。我可能找到了处理数据的方法,但这是一个可靠的方法。如果我想要中间结果中列出的所有商店和产品类型,即使是销售额为零的产品类型,该怎么办? –

1

我觉得是刚刚分离的查询是最简单的:

select Store, 
    (Select count(distinct Product) from products as p2 where p2.Store = p1.Store), 
    (Select count(distinct Product) from products as p3 where p3.Store = p1.Store and p3.Discount = "Yes") 
from products p1 
group by Store 

(如果它是关于大表,一定要测试你的表现)

+0

我实际上并不知道我可以在列列表中进行选择。如果没有别的,我在那里学到了一些东西:D谢谢! –