2010-03-24 144 views
0

在過去的幾天裏,我一直在試圖找到一種方法來從包含我稱爲日常計數的表中提取非常重要的一組信息。我有一張桌子,設置如下。SQL一個表彙總

person|company|prod1|prod2|prod3|gen_date 

每個公司有不止一個人,每個人可以有他們已經購買的產品的不同組合。我一直試圖弄清楚的是一個SQL語句,它將列出每個公司購買特定產品的人數。所以類似這樣的輸出:

Comp ABC | 13 Prod1 | 3 Prod2 | 5 Prod 3 
Comp DEF | 2 Prod1 | 15 Prod2 | 0 Prod 3 
Comp HIJ | 0 Prod1 | 0 Prod2 | 7 Prod 3 

目前,如果一個人沒有選擇的產品所存儲的值是NULL

最好我現在有3個不同的語句,如果自己運行,可以產生這些信息。

SELECT Count(person) as puchases, company 
FROM Sales WHERE prod1 = '1' and gendate = '3/24/2010' 
Group BY company 
+1

http://en.wikipedia.org/wiki/First_normal_form – 2010-03-24 20:43:22

+0

這並不違反1NF。 3NF,也許。 – Aaronaught 2010-03-24 20:52:22

回答

3
SELECT  company, 
      SUM(COALESCE(prod1, 0)) AS total_prod1, 
      SUM(COALESCE(prod2, 0)) AS total_prod2, 
      SUM(COALESCE(prod3, 0)) AS total_prod3 
FROM  Sales 
WHERE  gendate = '2010-03-24' 
GROUP BY company 

但你絕對應該正常化你的表 - 在4分割它:

  • 公司,
  • 人,
  • 商品,
  • Person_Product_Purchase(含購買日期)。
+0

我同意我會規範化數據,但對於這個特定的項目,這不是一個選項,因爲我不會提到的理由。但是,非常感謝。我不是數據庫人員。 – Lostdrifter 2010-03-24 20:57:49

0

如果你只是要檢查的值是否在任何產品領域,然後將其簡單地與OR運營商做的:

SELECT company, COUNT(person) as purchases 
FROM Sales 
WHERE (prod1 = '1' OR prod2 = '1' OR prod3 = '1') 
AND gendate = '3/24/2010' 
GROUP BY company 

這不會但是表現非常好,而且你很難得到它的表現,因爲你的模式還沒有正確的標準化。如果可以的話,你應該把它固定到這樣的事情:

Person (PersonID, CompanyID) 
Sales (PurchaseID, PersonID, ProductID, GenDate) 

那麼這個查詢(以及許多其他查詢)將是一個更容易寫:

SELECT p.CompanyID, COUNT(*) AS purchases 
FROM Person p 
INNER JOIN Sales s 
    ON s.PersonID = p.PersonID 
WHERE s.ProductID = 1 
AND s.GenDate = '20100324' 
GROUP BY p.CompanyID