2011-08-02 94 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謝謝! –