2010-03-24 3 views
0

В течение последних нескольких дней я пытался найти способ вытащить очень важный набор информации из таблицы, содержащей то, что я называю ежедневными подсчетами. У меня есть таблица, которая настраивается следующим образом.SQL one table aggregation

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 –

+0

Это не нарушает 1NF. 3NF, возможно. – Aaronaught

ответ

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:

  • Company,
  • Person,
  • Продукт,
  • Person_Product_Purchase (с датой покупки).
+0

Согласен Я нормализую данные, но для этого конкретного проекта, который не является вариантом по причинам, о которых я не буду упоминать. Но, спасибо большое. Я не человек базы данных. – Lostdrifter

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