2013-08-21 2 views
0

У меня есть структура таблицы, как это:Это можно сделать в SQL-запросе? (Вроде диаграммы Венна)

  • месяц (DateTime)
  • счета (INT)
  • продукта (интермедиат)
  • AmountPaid (INT)

и некоторые данные пример:

month  account product amountPaid 
------------------------------------ 
1-1-2012 1  1  50 
2-1-2012 1  1  50 
2-1-2012 2  1  150 
2-1-2012 2  2  100 

То, что я хотел бы это запрос, который может сказать мне,

  1. Для каждого месяца, количество счетов, которые заплатили за единственным продуктом 1.
  2. Количество счетов, которые выплачиваются только продукт 2 .
  3. и количество счетов, оплаченных для обоих продуктов 1 и 2.

Кроме того, продукты, которые каждый платит за счет может меняться от месяца к месяцу. Например, за один месяц учетная запись может оплатить только продукт 1, следующий месяц, как продукты 1 и 2, так и в следующем месяце, только продукт 2.

Это можно сделать в SQL-запросе?

Результирующий набор может понравиться что-то вроде:

month  product count 
------------------------ 
1-1-2012 1  10 
1-1-2012 2  5 
1-1-2012 1+2  3 
2-1-2012 1  8 
2-1-2012 2  4 
2-1-2012 1+2  2 
+0

Сколько различных продуктов Вы? –

+0

Просто два продукта 1 и 2. –

+0

Истинный ответ: SQL может делать все, что угодно, с достаточным программированием. С каждым выпуском все становится намного проще. Вероятно, вы захотите заглянуть в хранимую процедуру для запуска этого типа запроса, и, скорее всего, для каждого цикла будет использоваться курсор. – ps2goat

ответ

4

Вы можете сделать это с помощью одного запроса SQL, но мое решение не является динамическим. Если ваши продукты меняются, вам нужно будет обновить запрос для добавления/удаления продуктов, которые вы хотите отобразить. См SQL Fiddle для работы примера в SQL Server 2008.

with AccPay as (
select 
    pay_month, 
    account, 
    sum(case when product=1 then 1 else 0 end) as prod1_pay, 
    sum(case when product=2 then 1 else 0 end) as prod2_pay 
from payments p 
group by 
    pay_month, 
    account 
) 
select 
pay_month, 
sum(case when prod1_pay>=1 and prod2_pay=0 then 1 else 0 end) as prod1_only, 
sum(case when prod2_pay>=1 and prod1_pay=0 then 1 else 0 end) as prod2_only, 
sum(case when prod1_pay>=1 and prod2_pay>=1 then 1 else 0 end) as prod1_and_prod2 
from AccPay 
group by 
pay_month 
; 

ИЛИ

with AccPay as (
select 
    pay_month, 
    account, 
    sum(case when product=1 then 1 else 0 end) as prod1_pay, 
    sum(case when product=2 then 1 else 0 end) as prod2_pay 
from payments p 
group by 
    pay_month, 
    account 
) 
select 
pay_month, 
'1' as product, 
count(*) as count 
from AccPay 
where prod1_pay>=1 and prod2_pay=0 
group by 
pay_month 
union all 
select 
pay_month, 
'2' as product, 
count(*) as count 
from AccPay 
where prod2_pay>=1 and prod1_pay=0 
group by 
pay_month 
union all 
select 
pay_month, 
'1+2' as product, 
count(*) as count 
from AccPay 
where prod1_pay>=1 and prod2_pay>=1 
group by 
pay_month 

; 
0

Поскольку есть только два изделия есть простое решение. В этом запросе я предполагаю, что имя вашей таблицы - это данные, а число три обозначает продукт 1 + 2.

select month, sum (product) as products, count (number) as number 
from (
    select month, product, count (account) as number 
    from data 
    group by month, product 
) as t 
group by month 

В mysql существует функция group_concat, которая выполняет только это (она возвращает «1 + 2»). В MS Sql он не существовал еще в 2000 году, но, возможно, он был введен с тех пор.

0

Попробуйте это. Другие могут отредактировать, но это то, что у меня есть.

with x as (select [month], case when HasProduct1 = 1 and HasProduct2 = 1 then '1+2' 
        when HasProduct1 = 1 then '1' 
        when HasProduct2 = 1 then '2' else null end as "Product" 
    from 
    (select s1.[month], 
     case when exists(select s2.product 
        from sales s2 
         where s2.[month] = s1.[month] and 
          s2.account = s1.account and 
          s2.product = 1) then 1 else 0 end as HasProduct1, 
     case when exists(select s2.product 
        from sales s2 
         where s2.[month] = s1.[month] and 
          s2.account = s1.account and 
          s2.product = 2) then 1 else 0 end as HasProduct2 
     from sales s1) w 
) 
select [month], 
     Product, 
     (select count(*) from x x2 where x2.Product = x.Product) "Count" 
from x 
group by [month], Product 
Смежные вопросы