我想用下面存储的proc来计算出勤率,但它返回的值不正确。任何人都可以帮助我发现我的sp plz中的错误。
CREATE PROCEDURE [dbo].[percentage]
@stdid int,
@strtdate date,
@enddate date
AS
BEGIN
Select [std_status],
((select Count(std_status) where (std_status='P')) * 100 /
(Select Count(*) From [DB].[dbo].[attendance] where admission_Id_int=@stdid and
(entry_date BETWEEN @strtdate and @enddate)))
as attendencepercentage
From [DB].[dbo].[attendance]
where std_status='P' and admission_Id_int=@stdid
Group By std_status
END
答案 0 :(得分:0)
我无法理解您的查询。所以让我们从这个开始吧。
下面我有很多条款。您需要确定哪些是您的百分比的分子和分母。我无法从你的查询中解决这个问题。
select
sum(case when std_status='P' THEN 1 ELSE 0 END) as Term1,
sum(case when admission_Id_int=@stdid THEN 1 ELSE 0 END) as Term2,
sum(case when std_status='P' and admission_Id_int=@stdid THEN 1 ELSE 0 END) as Term3,
sum(case when std_status='P' THEN 1 ELSE 0 END) /
sum(case when admission_Id_int=@stdid THEN 1 ELSE 0 END) as SampleDivisionOfTerm1AndTerm2
From [DB].[dbo].[attendance]
where entry_date BETWEEN @strtdate and @enddate
Group By std_status
答案 1 :(得分:0)
您的查询返回错误百分比的原因是因为'P'
行的数量不包括entry_date
上的过滤器,而其他计数则包含@strtdate
。这意味着,对于@enddate
和entry_date
指定的相当小的范围,第一个计数可能超过第二个计数,因此除法的结果可能会大于100%。
所以,也许这个问题的一个简单解决方案就是在主WHERE子句中重复Select [std_status],
((select Count(std_status) where (std_status='P')) * 100 /
(Select Count(*) From [DB].[dbo].[attendance] where admission_Id_int=@stdid and
(entry_date BETWEEN @strtdate and @enddate)))
as attendencepercentage
From [DB].[dbo].[attendance]
where std_status='P' and admission_Id_int=@stdid
and (entry_date BETWEEN @strtdate and @enddate)
Group By std_status
过滤器:
(select Count(std_status) where (std_status='P'))
然而,正如所写,这样的查询将是不必要的复杂。例如,此子查询
COUNT(*)
完全是多余的,可以简单地重写
std_status='P'
因为主WHERE子句已经有SELECT
std_status = 'P',
AttendancePercentage = COUNT(CASE std_status WHEN 'P' THEN 1 END) * 100 / COUNT(*)
FROM
[DB].[dbo].[attendance]
WHERE
admission_Id_int = @stdid
AND entry_date BETWEEN @strtdate and @enddate
;
过滤器。但实际上,您可以以避免任何子查询的方式重写整个查询。这是一个例子:
std_status
上述查询检索与指定参数匹配的所有行,而不考虑COUNT(*)
,分别计算所有行('P'
)和匹配COUNT(CASE std_status WHEN 'P' THEN 1 END)
状态(AttendancePercentage
)的行并使用结果来计算GROUP BY std_status
。
还要注意重写中没有std_status
。在那里不需要它,因为其中一个计数完全忽略std_status
而另一个计数使用不同的列。
我不确定您是否确实需要输出中的{{1}}列,但是如果您这样做并且必须显示计算百分比的状态,我将其添加为带有硬编码的计算列值。否则,该列似乎是多余的,可以轻松删除。