随着时间的推移重复输入计数

时间:2016-05-12 15:03:13

标签: sql tsql sql-server-2012

这是我的第一个stackoverflow问题,所以请保持温和; - )

我有一张包含唯一customerID的表格,以及一张包含特定交易类型交易的表格(购买,预售等)

我想要的是所有曾经完成特定交易类型的客户。但如果客户在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 个答案:

答案 0 :(得分:0)

由于您希望按Customers计算TransactionType,因此您应该按CustomerIDTransactionType进行分组,而不是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

这应该返回完成类型交易的人数,至少一次,无论年份如何。

答案 1 :(得分:0)

使用:

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以获取有关此功能的聚合函数的更多信息。

答案 2 :(得分:0)

当您查看它时,它是您感兴趣的每个客户的第一个预售。您可以通过为每个客户选择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;