如何将序列#添加到子“日志”记录的列名称前(用于报告工具)

时间:2013-07-02 04:44:55

标签: sql sql-server tsql

我有一个父表CASES和子表UPDATES。每日例程记录从CASESUPDATES表的每一行。这意味着每个CASE都有一个,然后是多个UPDATES

CaseID  | CaseStatus | [other fields]
=====================================
PK(int) | Free text  | Free text...

更新

UpdateID | UpdateDate   | CaseID  | CaseStatus | [other fields]
===============================================================
PK(int)  | Date Entered | FK(int) | Free text  | Free text...

我可以使用以下查询 -

select *,
  (Row_Number() over (partition by CaseID order by UpdateDate desc)) as SeqNo
from UPDATES order by SeqNo, CaseId

UPDATES数据分组并排序到#TEMP表中,例如 -

SeqNo | UpdateID | UpdateDate  | CaseID | CaseStatus | [other fields]
====================================================================
1     | 9876     | 30-Jun-2013 | 345    | [free text...]
1     | 9875     | 30-Jun-2013 | 789    | [free text...]
2     | 9765     | 29-Jun-2013 | 345    | [free text...]
2     | 9764     | 29-Jun-2013 | 789    | [free text...]
3     | 9654     | 28-Jun-2013 | 345    | [free text...]
4     | 9653     | 27-Jun-2013 | 345    | [free text...]

我们使用第三方报告库。要启用特定UPDATES作为CASES的子组件的报告,我需要一个将数据作为一组平面结果返回的查询。换句话说,我需要提供类似sq2_CaseStatus的内容来表示任何给定UPDATES.CaseStatusCASE集合中最新的CASES数据。 (即,CaseId传递给报告代码,报告代码运行我的存储过程,我的SP查询和返回结果集,报告结果集列上的代码键以查找数据。)

我只需要从SeqNo表中提供12个最新的UPDATES值(1 - 12)。但我正在努力解决如何在主要报告查询中查询和返回此数据。

问题:如何从UPDATES查询和返回数据,以便显示SeqNo,并作为任何报告字段的前缀提供?

如果我的线性思维在这里当然是道歉的话,请提前道歉......

在我的报告查询中,有一个SELECT语句可以抓取CASES中的所有数据,并从其他链接表中选择数据。在这个SELECT中,我可以使用'循环'技术来调用特殊函数吗?

这个特殊函数将采用一个计数器变量(从1到12),使用该变量通过#TEMP查询我的分组/顺序SeqNo表,并使用该变量将数据呈现在'编码'列。因此,我最终将12个子表链接回我的CASE记录,如 -

SeqNo | UpdateID | sq1_UpdateDate  | CaseID | sq1_CaseStatus | sq1_[other fields]
=================================================================================
1     | 9876     | 30-Jun-2013     | 345    | [free text...]
1     | 9875     | 30-Jun-2013     | 789    | [free text...]

SeqNo | UpdateID | sq2_UpdateDate  | CaseID | sq2_CaseStatus | sq2_[other fields]
=================================================================================
2     | 9765     | 29-Jun-2013     | 345    | [free text...]
2     | 9764     | 29-Jun-2013     | 789    | [free text...]

and so on...

我认为这可行。但是有可能在SELECT语句中以这种方式“循环”吗?

注意 - 实际上,CASESUPDATES表格都很宽,所以我放弃了“扩展”单个#TEMP表的任何选项(即,为每个SeqNo呈现所有1-12 CaseId组数据。此外,我意识到对报告界面代码的更改可以帮助解决问题 - 但我正在努力避免这种(代价高昂的)选项。

更新/解决方法:好吧,我不得不求助于我最初放弃的单一'宽'#TEMP表解决方案。我使用递归脚本来帮助生成我需要的MAX语句的长列表 - 这些语句产生了前缀列名。然后我将这些与INNER JOIN(执行排序)组合在一个表值函数中。有点像...

SELECT up.CaseId AS CaseId,
       MAX(CASE sq.SeqNo WHEN 1 THEN up.UpdateDate ELSE '' END) AS sq1_UpdateDate,
       MAX(CASE sq.SeqNo WHEN 2 THEN up.UpdateDate ELSE '' END) AS sq2_UpdateDate,
       ...
       ...<up to sq12_ for all fields>...
       ...
FROM   UPDATES up
INNER JOIN  (
  SELECT UpdateId,
         Row_Number() OVER (PARTITION BY CaseId ORDER BY UpdateDate Desc) AS SeqNo
  FROM   UPDATES ) sq ON sq.UpdateId = up.UpdateId
GROUP BY up.CaseId

1 个答案:

答案 0 :(得分:1)

它不漂亮......但它应该有用。

您可以在存储过程中使用Dynamic Sql来获取特定子行并动态构造名称:

(您可能需要使用##将临时表更改为全局临时表,以便实现此功能)

CREATE PROCEDURE GetChild @chilSeq int
AS
DECLARE @sChild varchar(10)
set @sChild = convert(varchar(10), @childSeq)
DECLARE @dsql varchar(4000)
set @dsql = 'SELECT SeqNo, UpdateID, [sq'+ @sChild +'_UpdateDate], CaseID, [sq'+ @sChild +'_CaseStatus], [sq'+ @sChild +'_[other fields]]
FROM #temp where SeqNo = ' + @sChild

execute @dsql
GO

就像我说的那样,它并不漂亮,甚至不建议用于性能考虑,但在您的情况下可能是您正在寻找的解决方案。