读书人

请问擅长存储过程的同行

发布时间: 2012-07-05 07:59:17 作者: rapoo

请教擅长存储过程的同行!
TerminalNO DateTime Mileage CarNo
1001 2012-06-27 12:00:00 10 XB1
1001 2012-06-27 12:01:00 11 XB1
1001 2012-06-28 12:02:00 12 XB1

1002 2012-06-28 12:03:00 40 XB2
1002 2012-06-29 12:04:00 46 XB2
1002 2012-06-30 12:05:00 49 XB2

1003 2012-06-29 12:06:00 14 XB2
1003 2012-06-29 12:07:00 20 XB2
1003 2012-06-30 12:08:00 37 XB2

不同时间的数据在不同的表中,例Path20120627,Path20120628

有三个表,结构如下:

Terminal(id,TerminalNo)
GpsPathXXX( id,TerminalNO,Mileage,GpsTime)
Car(id,CarNO,TerminalN0)
查询参数为:CarNo(一个或多个) 开始时间、结束时间。

需求如下:

查询出不同TerminalNO的最大时间(GpsTime)和最小时间(GpsTime)的的Mileage,然后相减(最大时间和最小时间是由用户输入的,这里就存在一个问题,如果输入的不是同一天,就要跨表查询,如果CarNo参数是个数组,就要循环查)

返回结果集如下:

TerminalNO StartTime EndTime Mileage CarNo
1001 2012-06-27 12:00:00 2012-06-28 12:02:00 2 XB1
1002 2012-06-28 12:03:00 2012-06-29 12:05:00 9 XB2
1003 2012-06-29 12:06:00 2012-06-30 12:08:00 23 XB3

我已写出:日期为同一天,CarNo只有一个的存储过程,

SQL code
ALTER PROCEDURE [dbo].[spMileageStatement](    @CarNo varchar(30),    @StartTime datetime,    @EndTime datetime,    @Result varchar(10) out    )ASDECLARE @Mileage VARCHAR(20)--里程DECLARE @SQL VARCHAR(100)DECLARE @GpsStartDay VARCHAR(8)--开始时间DECLARE @GpsEndDay VARCHAR(8)--结束时间DECLARE @GpsTime varchar(8)DECLARE @WHERES VARCHAR(1000)DECLARE @TEMP1 VARCHAR(1000)DECLARE @TEMP2 VARCHAR(1000)SET @GpsStartDay = CONVERT( VARCHAR(8), CAST(FLOOR(CAST(@StartTime AS FLOAT)) AS DATETIME), 112)SET @GpsEndDay=CONVERT( VARCHAR(8), CAST(FLOOR(CAST(@EndTime AS FLOAT)) AS DATETIME), 112)SET @WHERES=' AND 1=1'IF(@CarNo<>'' or @CarNo is not null)--查全部或者根据车牌号查BEGIN    SET @WHERES=' AND Car.CarNo='+@CarNoEND--结束时间的里程    SET @TEMP1='SELECT  top 1 Mileage    FROM  dbo.Car     INNER JOIN dbo.Terminal ON dbo.Car.CarId = dbo.Terminal.CarId     INNER JOIN dbo.GpsPath'+@GpsTime+' ON dbo.Terminal.TerminalNo = dbo.GpsPath'+@GpsTime+'.TerminalNo    WHERE GpsTime<='+@EndTime+@WHERES+'    ORDER BY GpsTime desc '    --开始时间的里程    SET @TEMP2='SELECT  top 1 Mileage    FROM  dbo.Car     INNER JOIN dbo.Terminal ON dbo.Car.CarId = dbo.Terminal.CarId     INNER JOIN dbo.GpsPath'+@GpsTime+' ON dbo.Terminal.TerminalNo = dbo.GpsPath'+@GpsTime+'.TerminalNo    WHERE GpsTime>='+@StartTime+@WHERES+'    ORDER BY GpsTime asc 'SET @Mileage=@TEMP1-@TEMP2EXEC(@Mileage)IF(@Mileage>0)--如果大于0,说明数据正常,如果小于0,说明基础数据不正常。BEGIN    SET @SQL='SELECT  MIN(UploadTime)AS 开始时间,MAX(UploadTime)AS 结束时间,CompanyName,Car.CarNo,'+@Mileage+'FROM  dbo.Car INNER JOIN dbo.Terminal ON dbo.Car.CarId = dbo.Terminal.CarId INNER JOIN dbo.GpsPath'+@GpsTime+' ON dbo.Terminal.TerminalNo = dbo.GpsPath'+@GpsTime+'.TerminalNoINNER JOIN dbo.Company ON dbo.Car.CompanyId=dbo.Company.CompanyIdgroup by CompanyName,Car.CarNo'ENDELSEBEGIN    SET @Result='0'    RETURN ENDif(@GpsStartDay=@GpsEndDay)--开始时间与结束时间为同一天BEGIN    Set @GpsTime=@GpsStartDay--数据表为GpsPath加上这一天,例:GpsPath20120629    exec(@SQL)END

但剩下两个需求想了好久,都没写出一个完善的存储,而且上面存储的写的也不好,所以来请教各位同行。

[解决办法]
其实你这就是几个组合拼接啊

先判断用户输入的日期,
if d1=d2
.....
else if d1>d2
....

你的逻辑思路 很清晰, 自己拼接一下语句

然后 print @SQL
可以看哪里语法写错了。。。


------解决方案--------------------


探讨

说实话,我见到那密密麻麻的,头都疼,需求是一天好几变,引用:
其实你这就是几个组合拼接啊

先判断用户输入的日期,
if d1=d2
.....
else if d1>d2
....

你的逻辑思路 很清晰, 自己拼接一下语句

然后 print @SQL
可以看哪里语法写错了。。。

[解决办法]
这个问题不难,首先你得根据传入的时间判断在那个表中查询,这是第一步
第二步就是拼接SQL 查询语句,

自己跟着思路写吧,真的不难
[解决办法]
SQL code
--#1.如果CarNo参数是个数组,就分解这个数组,然后分别调用存储过程 spMileageStatement--#2.跨表查询问题,解决办法是用分区表来存储数据,但就目前的情况来看,当基础数据不正常时,势必会扫描所有的表。所以试着这样解决select [name] from sys.tables where [name] like 'GpsPath%'--然后循环:拼SQL查询数据是否在表中select top 1 Mileage from GpsPathXXXX where XXXX--计算之
[解决办法]
多写几个就不头痛了。。。
[解决办法]
你这个是业务逻辑问题,非技术问题,多找找思路,将问题化繁为简,往往更容易解决。

读书人网 >SQL Server

热点推荐