Это мой первый вопрос о переполнении стека, поэтому будьте осторожны ;-)

У меня есть таблица с уникальными идентификаторами клиентов и таблица, включающая их транзакции с определенным типом транзакции (покупка, предварительная продажа и т. Д.)

Я хочу подсчитать всех клиентов, которые однажды совершили транзакцию определенного типа. Но если клиент совершил подходящую транзакцию в 2014 году, я не хочу, чтобы этот клиент снова учитывался в 2015 году. Имеет ли это смысл?

Я пробовал следующее утверждение:

SELECT

datepart(yyyy,t.TransactionDate)
,count(DISTINCT c.customerID)

FROM Customers as c

   JOIN Transactions as t
   ON c.CustomerID = t.CustomerID

WHERE t.TransactionType = 'presell'
GROUP BY datepart(yyyy,t.TransactionDate)

Проблема в том, что, конечно, клиент может выполнять транзакцию одного и того же типа один раз в год. Таким образом, с помощью этого утверждения я считаю клиентов отдельными за год ... а не только один раз в целом.

РЕДАКТИРОВАТЬ: Давайте упростим задачу. Есть только одна таблица, и она выглядит примерно так:

CustomerTable

Поэтому, если я использую фильтр "Presell", мой результат должен выглядеть примерно так

enter image description here

В 2014 году клиент A провел предварительную продажу, в 2015 году клиент B провел предварительную продажу, в 2016 году клиент A снова провел предварительную продажу, но я не считаю этого клиента, потому что я уже считал его в 2014 году. Надеюсь, это проясняет ситуацию.

Спасибо за любой совет и помощь здесь.

3
s0ms0n 12 Май 2016 в 18:03

3 ответа

Лучший ответ

Когда вы смотрите на него, это первая предварительная продажа для каждого покупателя, который вас интересует. Вы можете легко получить это, выбрав MIN(TransactionDate) для каждого покупателя. Как только вы это сделаете, можете считать.

select year, count(*)
from
(
  select customerid, min(transactiondate) as year
  from transactions
  where transactiontype = 'Presell'
  group by customerid
) first_presells
group by year
order by year;
0
Thorsten Kettner 13 Май 2016 в 06:12

Поскольку вы хотите подсчитать Customers по TransactionType, вам следует группировать по CustomerID и TransactionType, а не по TransactionDate:

SELECT  datepart(yyyy,t.TransactionDate) -- this part won't work anymore without grouping it. Doesn't seem to be relevant to what you're selecting
    ,count(DISTINCT c.customerID)

FROM Customers as c

   JOIN Transactions as t
   ON c.CustomerID = t.CustomerID

WHERE t.TransactionType = 'presell'
GROUP BY c.CustomerID, t.TransactionType

Это должно вернуть количество людей, которые завершили транзакцию типа хотя бы один раз, независимо от года.

0
levelonehuman 12 Май 2016 в 15:12

Использование:

SELECT  datepart(yyyy,t.TransactionDate) ,
count(*) over (partition by c.CustomerID, t.TransactionType)

FROM Customers as c

   JOIN Transactions as t
   ON c.CustomerID = t.CustomerID

WHERE t.TransactionType = 'presell'

Вы можете посмотреть http: // www. .sqlteam.com / article / sql-sever-2005-using-over-with-aggregate-functions для получения дополнительной информации об агрегатных функциях, подобных этой.

0
Haytem BrB 12 Май 2016 в 15:13