虽然取两列的结果没有显示出正确的结果

时间:2013-09-04 08:18:52

标签: sql-server

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

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,其中dtime> ='2013-09-03 00:00:00.000'和dtime< ='2013-09-03 23:59:59.000'和DelEcode ='E003'我得到35行,但在执行存储过程时我只得到23个CntDelEcode计数

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

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

存储过程存在几个问题:

  1. 一种消除时间的奇怪方式(只是演员到目前为止)
  2. BETWEEN语句,用于比较字符串而非日期,因为+''语句。
  3. 在您实际需要datetime
  4. 时使用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