-2

我有一个这样的存储过程:

ALTER procedure [dbo].[Driverperformance] 
    @Ecode nvarchar(50), 
    @startdate datetime,
    @enddate datetime
as 
begin 

    declare @date1 datetime = CONVERT(datetime, @startdate + ' 00:01:00.000', 120);
    declare @date2 datetime = CONVERT(datetime, @enddate + ' 23:23:59.000', 120);

    SELECT 
        e.Ecode,CAST(q.dtime AS DATE) as Date, 
        e.Ename, 
        count(q.Ecode) CntEcode ,
        count(DelEcode) CntDelEcode
    FROM EmployeeMaster_tbl e 
    inner JOIN Transaction_tbl q 
        ON e.Ecode = q.Ecode where q.Ecode=@Ecode
        and dtime between '' + @date1 +'' and ''+@date2+'' 
    group by 
        e.Ecode, 
        e.Ename, 
        CAST(q.dtime AS date) 
    ORDER BY CAST(q.dtime AS date)--e.Ecode DESC
end

但我没有得到正确的 DelEcode 计数,当我像这样检查 DelEcode 的计数时,我的存储过程有什么问题:select * from Transaction_tbl where dtime >='2013-09-03 00:00:00.000' and dtime < ='2013-09-03 23:59:59.000' 和 DelEcode='E003' 得到 35 行,但在执行存储过程时只得到 23 个 CntDelEcode

4

2 回答 2

0

如果要计算不同“DelEcode”的数量,请尝试 count(distinct DelEcode)。如果没有,您将计算 DelEcode 值不为空的记录数。如果您执行连接,则计数将是笛卡尔积的结果,而不是不同 DelEcode 的数量。

于 2013-09-04T08:27:51.093 回答
0

我假设您使用 SQL Server 2008 或更高版本,因为您CAST(... as date)的代码中有

您的存储过程存在几个问题:

  1. 一种奇怪的剥夺时间的方法(只是到目前为止)
  2. 由于语句的原因,比较字符串而不是日期的 BETWEEN+''语句。
  3. datetime在您真正需要时使用参数date

最简单的方法是像这样重写存储过程

ALTER procedure [dbo].[Driverperformance] 
    @Ecode nvarchar(50), 
    @startdate date,
    @enddate date
as 
begin 

    SELECT 
        e.Ecode,CAST(q.dtime AS DATE) as Date, 
        e.Ename, 
        count(q.Ecode) AS CntEcode ,
        count(DelEcode) AS CntDelEcode
    FROM EmployeeMaster_tbl e 
    inner JOIN Transaction_tbl q 
        ON e.Ecode = q.Ecode 
    where q.Ecode=@Ecode
        and @startdate <= dtime 
        and dtime < @enddate
    group by 
        e.Ecode, 
        e.Ename, 
        CAST(q.dtime AS date) 
    ORDER BY CAST(q.dtime AS date)--e.Ecode DESC
end

调用此存储过程并传递datetime值的代码不应该有问题,因为时间部分将被截断。仅当您传递字符串文字而不是日期时才会遇到问题,其格式 SQL Server 无法从您的设置中识别

如果您必须datetime在存储过程的其他部分中使用参数,您可以进行简单的迄今为止的转换:

ALTER procedure [dbo].[Driverperformance] 
    @Ecode nvarchar(50), 
    @startdate datetime,
    @enddate datetime
as 
begin 

    declare @date1 date= cast(@startdate as date);
    declare @date2 date= cast(@enddate as date);

    SELECT 
        e.Ecode,CAST(q.dtime AS DATE) as Date, 
        e.Ename, 
        count(q.Ecode) AS CntEcode ,
        count(DelEcode) AS CntDelEcode
    FROM EmployeeMaster_tbl e 
    inner JOIN Transaction_tbl q 
        ON e.Ecode = q.Ecode 
    where q.Ecode=@Ecode
        and @date1 <= dtime 
        and dtime < @date2
    group by 
        e.Ecode, 
        e.Ename, 
        CAST(q.dtime AS date) 
    ORDER BY CAST(q.dtime AS date)--e.Ecode DESC
end

您还可以ORDER BY通过重新排序您的GROUP BY. 对结果进行分组排序,因此您可以使用GROUP BY CAST(q.dtime AS date) , e.Ecode, e.Ename按日期、Ecode 和 Ename 获取结果排序

于 2013-09-04T09:47:03.793 回答