【发布时间】:2015-03-20 00:46:50
【问题描述】:
我有一个 SQL Server TSQL 问题。我的存储过程正在运行 非常缓慢地。关于使用集合操作改进这些查询的任何建议 将不胜感激。
请记住,我无法控制数据的存储方式。
我有两个表格,格式如下:
人员 ID、姓名、DeletedFlag、SchedTotal、WorkedTotal、DeptNum、DeptName、 [和这个问题的其他 20 个不相关的列] 这是一个临时表 预填充用户选择的人员和用户 可以访问。
人员 ID、记录类型、年份、HexMap
对于每个人,一个特定的记录将有两条或零条记录 年。一份用于计划时间的记录,一份用于工作时间的记录。十六进制图 是一个字符串(每两个字符代表总计划或工作 时间)。我最多可以有 732 个字符(每天一对),总是 从 1 月 1 日开始。我写了一个函数来拆分字符串,所以我不是 担心这个。
想要的结果
第一个表 SchedTotal 和 WorkedTotal 字段更新为总计 根据用户选择的日期从第二个表中获取。日期 范围可以在一个日历年内或跨多个日历年。
我可以做到,但我认为我采取的步骤太多了。下面是什么 我目前正在做。建议赞赏:
A. TEMP 结果表 1:对于用户的每个日历年 选择的日期范围(While 循环):将 上表 1 所列人员的 personid、recordtype 和 hexmap。
WHILE (@YearCount <= @YearEnd)
....
INSERT INTO #Tmp_HexMap (personid, hexMap, recordtype)
SELECT T1.personid, H.HexMap, H.recordtype
FROM [MyDatabase_' + CONVERT(Varchar(5),@DatabaseNum) + '].[dbo].[hextable] H
INNER JOIN #Tmp_Persons T1 ON T1.Personid = H.PersonID
WHERE Year = ' + CONVERT(Varchar(5),@YearCount)
B.临时结果表 2:仍处于每年的 While 循环中。一世 为每个人逐行计数(内部 While 循环) 并将我的十进制结果插入另一个临时表 十六进制拆分器函数——它返回一个带小数的表变量 结果。我添加了 personid 、预定或工作日期和预定 和工作时间。
WHILE (@PersonID IS NOT NULL)
....
INSERT INTO #Tmp_scheduledtime (personid, scheddate, scheduledworkedtime)
SELECT @personid as personid,
DATEADD(dd,(Row_Number() OVER(Order by (Select NULL))+(@CurrentStartInt-1)-1),@YearStartDate) AS SchedDate,
workedtime FROM Report_Maint.dbo.workedtimesplit(@HexMap,@CurrentStartInt,@WorkedTimeDateINT)
C.临时结果表 3 和 4:在 while 循环之外,我将总计插入临时表:
INSERT INTO #Tmp_Grouped1 (personid, ScheduledTotal, WorkedTotal)
SELECT personid, ISNULL(SUM(scheduledworkedtime),-1.00) From #Tmp_scheduledtime
GROUP BY personid
D.最后,我更新了原表:
'UPDATE #Tmp_Persons ' +
'SET HoursSched = ScheduledWorkedTotal ' +
'From #Tmp_Grouped1 TG ' +
'WHERE TG.Personid = #Tmp_Persons.Personid ' +
' AND #Tmp_persons.PeriodBegin >= ' + '''' + CONVERT(nvarchar(24),@DateBegin,121) + '''' + ' ' +
'AND #Tmp_persons.PeriodEnd <= ' + '''' + CONVERT(nvarchar(24),@DateEnd,121) + ''''
关于将这些变成一两个查询而不是通过 while 循环的任何想法? 感谢您的帮助!
标记
【问题讨论】:
-
能否提供一些示例数据和预期结果/
-
是的,我需要您列出所有表格和使用的列以及示例数据和您想要的结果,以帮助您。
-
为简单起见(和换行)假设每年只有 25 天(十六进制对)。用户查询 2013 年 1 月 16 日 - 2015 年 1 月 18 日的开始范围。这意味着我们从第 16 天(第 32 个字符)开始计算 2013 十六进制对,并在第 18 天(第 36 个字符)结束计算 2015 十六进制对.临时表 1:PersonID,Name,DeletedFlag,SchedTotal,WorkedTotal,DeptNum,DeptName 1,Joe,N,-1,-1,Dept1,AcctDept 2,Bill,Y,-1,-1,Dept2,Credit 3,Bob ,N,-1,-1,Dept4,HR 4,Jill,N,-1,-1,Dept1,AcctDept 5,Marcy,N,-1,-1,Dept2,Credit
-
第2部分响应: - 临时表2:是PersonID,记录类型,年份,HexMap 1,0,2013,00006060606060000060606060600000606060606000006060 [672] 1,1,2013,00006F606060600000756060606000006F6060600000666060 [693] 1,0,2014 ,004A6060006060604A60000060604A60000000606060606000 [1566] 1,1,2014,00575B000049645D5A625C00605A572D5347005F585B7F5E00 [1691] 1,0,2015,60606000006060606060000060606060600000606060606054 [1248] 1,1,2015,00000000005F60606060000060606060000000600060606000 [863] 2,0,2015,70606C73006A79606E000000749578687100006F6B9471676F [1466] 跨度>
-
2,1,2015,006D776F717179006F6E006A6C7B006B72696D6971007B7569 [1570] 3,0,2014,00006040005F6060606000006060 [831] 3,1,2014,0060606400606060606000006060 [964] 4,0,2014,00000000666031606064006060600060000060606060606300 [1502] 4, 1,2014,60600000606060606000006060606060000060606060600000 [1632] 4,0,2015,0080666F6D723800767C717B750072696867346C746B756A63 [1641] 4,1,2015,69656E6363006522000063697E6B416D007067696768000000 [1372] 跨度>
标签: sql sql-server database tsql report