sql - 计算每 30 天一次的响应 SQL

标签 sql sql-server-2008-r2

如果我有一位客户在 30 天内多次回复同一个调查,我只想计算一次。有人可以告诉我执行此操作的代码吗?

create table #Something
(
         CustID Char(10),
    SurveyId char(5),
    ResponseDate datetime
)

insert #Something
select 'Cust1', '100', '5/6/13' union all
select 'Cust1', '100', '5/13/13' union all
select 'Cust2', '100', '4/20/13' union all
select 'Cust2', '100', '5/22/13'


select distinct custid, SurveyId, Count(custid) as CountResponse from #Something
group by CustID, SurveyId 

上面的代码只给出了响应的总数,不知道如何编码才能每 30 天只计数一次。

我正在寻找的输出应该是这样的:

CustomerID     SurveyId    CountResponse
Cust1          100         1
Cust2          100         2

最佳答案

根据您希望从第一次提交调查开始算起的 30 天计算周期的理论,这是一个(粗略的)解决方案。

declare @Something table
(
    CustID Char(10),
    SurveyId char(5),
    ResponseDate datetime
)

insert @Something
select 'Cust1', '100', '5/6/13' union all
select 'Cust1', '100', '5/13/13' union all
select 'Cust1', '100', '7/13/13' union all
select 'Cust2', '100', '4/20/13' union all
select 'Cust2', '100', '5/22/13' union all
select 'Cust2', '100', '7/20/13' union all
select 'Cust2', '100', '7/24/13' union all
select 'Cust2', '100', '9/28/13' 

--SELECT CustID,SurveyId,COUNT(*) FROM (

select a.CustID,a.SurveyId,b.ResponseStart,--CONVERT(int,a.ResponseDate-b.ResponseStart),
CASE 
    WHEN CONVERT(int,a.ResponseDate-b.ResponseStart) > 30 
    THEN ((CONVERT(int,a.ResponseDate-b.ResponseStart))-(CONVERT(int,a.ResponseDate-b.ResponseStart) % 30))/30+1
    ELSE 1
END CustomPeriod -- defines periods 30 days out from first entry of survey
from @Something a
inner join
(select CustID,SurveyId,MIN(ResponseDate) ResponseStart
from @Something
group by CustID,SurveyId) b
on a.SurveyId=b.SurveyId
and a.CustID=b.CustID
group by a.CustID,a.SurveyId,b.ResponseStart,
CASE 
    WHEN CONVERT(int,a.ResponseDate-b.ResponseStart) > 30 
    THEN ((CONVERT(int,a.ResponseDate-b.ResponseStart))-(CONVERT(int,a.ResponseDate-b.ResponseStart) % 30))/30+1
    ELSE 1
END

--) x GROUP BY CustID,SurveyId

至少您可能希望使 CASE 语句成为一个函数,这样它读起来更清晰一些。更好的做法是在单独的表中定义显式窗口。如果您想避免这样的情况,例如在第一阶段结束时返回调查,几天后在第二阶段返回另一个调查,这可能是不可行的。

如果可能,您应该考虑在输入时处理它。例如,如果您在在线调查中识别客户,请拒绝填写调查的尝试。或者,如果有人邮寄这些东西,如果有人在 30 天内来,让数据录入人员拒绝。

或者,沿着与“狂野和疯狂”相同的思路,添加一个位和一个 INSERT 触发器。仅当在该时间段内未找到针对该客户的该类型调查时才打开该位。

总的来说,更完整地表述这个问题会有所帮助。不过,我确实很欣赏实际的编码示例。

关于sql - 计算每 30 天一次的响应 SQL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17579970/

相关文章:

具有多个计数和分组依据的 MySql 过程

SQL 比较 Access 中保存的日期与今天的日期不起作用

installation - SQL Server 2008 R2 安装期间缺少 "instance configuration"步骤

php - 如何使用 Propel 2 ORM 在一个查询中将多行插入数据库?

sql - 如何在 SQL Server 上的 CASE 中使用 "IN"?

sql-server - 低权限用户执行存储过程时的表权限

sql-server - 最大化 SQL Server Service Broker 吞吐量

sql - 获取SQL语句返回的列

填充唯一标识符空白行的SQL方法

sql-server - 如何使用最新记录更新 SQL Server 表