2010-03-24 86 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