【问题标题】:SQL one table aggregationSQL一表聚合
【发布时间】:2011-01-31 11:01:21
【问题描述】:

在过去的几天里,我一直在尝试找到一种方法来从包含我称之为每日计数的表中提取一组非常重要的信息。我有一个设置如下的表。

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

【问题讨论】:

标签: sql aggregation


【解决方案1】:
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(带有购买日期)。

【讨论】:

  • 我同意我会规范化数据,但对于这个特定的项目,这不是一个选项,原因我不会提及听到。但是,非常感谢。我不是数据库人。
【解决方案2】:

如果您只想检查该值是否在任何产品字段中,那么只需使用 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

【讨论】:

    猜你喜欢
    • 2017-08-22
    • 1970-01-01
    • 2015-02-20
    • 2014-12-15
    • 1970-01-01
    • 2020-11-17
    • 2014-11-18
    • 2022-01-25
    • 1970-01-01
    相关资源
    最近更新 更多