不同值的单独列

时间:2018-11-23 22:22:09

标签: sql sql-server tsql

from select import select
import sys

def timed_input(prompt, timeout):
    """Wait for user input, or timeout.

    Arguments:
    prompt  -- String to present to user.
    timeout -- Seconds to wait for input before returning None.

    Return:
    User input string.  Empty string is user only gave Enter key input.
    None for timeout.
    """
    sys.stdout.write('(waiting %d seconds) ' % (int(timeout),))
    sys.stdout.write(prompt)
    sys.stdout.flush()
    rlist, wlist, xlist = select([sys.stdin], [], [], timeout)
    if rlist:
        return sys.stdin.readline().strip()
    print()
    return None

我有一项调查得出的数据,用户每天可以填写多次。 它允许用户选择5个选项中的1个(0、25、50、75、100)。它具有用于配置文件ID,创建于和值的列

我正在尝试获取用户选择每个选项的次数的百分比。我也只想返回具有10个或更多响应的配置文件。假设个人资料1选择了0 5次,25 2次,50 1次,75 2次,100 0次我希望它返回

SELECT 
[profile_id]
,(SELECT COUNT(*) FROM [dbo].[SurveyResponse] sr0 WHERE sr.profile_id = profile_id AND sr0.[value] = '0' AND sr0.[created_At] > DATEADD(MONTH,-3,GETDATE()) )/COUNT(*) as [0 Responses]
,(SELECT COUNT(*) FROM [dbo].[SurveyResponse] sr25 WHERE sr.profile_id = profile_id AND sr25.[value] = '25'AND sr25.[created_At] > DATEADD(MONTH,-3,GETDATE()))/COUNT(*) as [25 Responses]
,(SELECT COUNT(*) FROM [dbo].[SurveyResponse] sr50 WHERE sr.profile_id = profile_id AND sr50.[value] = '50' AND sr50.[created_At] > DATEADD(MONTH,-3,GETDATE()))/COUNT(*) as [50 Responses]
,(SELECT COUNT(*) FROM [dbo].[SurveyResponse] sr75 WHERE sr.profile_id = profile_id AND sr75.[value] = '75' AND sr75.[created_At] > DATEADD(MONTH,-3,GETDATE()))/COUNT(*) as [75 Responses]
,(SELECT COUNT(*) FROM [dbo].[SurveyResponse] sr100 WHERE sr.profile_id = profile_id AND sr100.[value] = '100' AND sr100.[created_At] > DATEADD(MONTH,-3,GETDATE()))/COUNT(*) as [100 Responses]
,COUNT(*) as [Total Responses]
FROM [dbo].[SurveyResponse] sr
  WHERE [created_At] > DATEADD(MONTH,-3,GETDATE())
  GROUP BY [profile_id]
  HAVING COUNT(*) > 10

与总响应相比,我可以将每个响应的计数分散出来,但是必须有一种比我上面有更好的方法来实现这一点,并且还必须具有一种显示%s的方法。

这是在SQL Server中

有什么想法吗?

2 个答案:

答案 0 :(得分:2)

您正在使事情变得更复杂。您不需要子查询。

select 
  profile_id,
  count(case when value =   0 then 1 end) * 100.0 / count(*) as [0 Responses],
  count(case when value =  25 then 1 end) * 100.0 / count(*) as [25 Responses],
  count(case when value =  50 then 1 end) * 100.0 / count(*) as [50 Responses],
  count(case when value =  75 then 1 end) * 100.0 / count(*) as [75 Responses],
  count(case when value = 100 then 1 end) * 100.0 / count(*) as [100 Responses],
  count(*) as [total responses]
from dbo.surveyresponse
where created_at > dateadd(month, -3, getdate())
group by profile_id
having count(*) > 10
order by profile_id;

您可能希望应用ROUND来获得更少的小数,尽管:-)

从SQL Server 2012开始,您可以使用FORMAT输出格式化的数字字符串。

答案 1 :(得分:1)

我想使用avg()简化此计算:

select profile_id,
       avg(case when value = 0 then 100.0 else 0 end) as [0 Responses],
       avg(case when value = 25 then 100.0 else 0 end) [25 Responses],
       avg(case when value = 50 then 100.0 else 0 end) as [50 Responses],
       avg(case when value = 75 then 100.0 else 0 end) as [75 Responses],
       avg(case when value = 100 then 100.0 else 0 end) as [100 Responses],
       count(*) as [total responses]
from dbo.surveyresponse
where created_at > dateadd(month, -3, getdate())
group by profile_id
having count(*) > 10
order by profile_id;