如何组合2列的字段来创建“矩阵”?

时间:2013-07-08 22:53:17

标签: sql-server

我的应用程序中有一个日志表,它只记录更改的数据,并将其他列留空。我现在要做的是创建一个视图,其中包含其中两列(类型和状态), 并创建一个结果集,该结果集返回该日志行条目上的Type和Status,假设一列或两列都可以为null。

例如,使用此数据:

Type Status AddDt

A    1      7/8/2013
NULL 2      7/7/2013
NULL 3      7/6/2013
NULL NULL   7/5/2013
B    NULL   7/4/2013
C    NULL   7/3/2013
C    4      7/2/2013

produce the resultset:
Type Status AddDt
A    1      7/8/2013
A    2      7/7/2013
A    3      7/6/2013
A    3      7/5/2013
B    3      7/4/2013
C    3      7/3/2013
C    4      7/2/2013

从那里我将弄清楚这些结果中第一次类型和状态是否满足某些条件,例如B类型和状态3(2013年7月4日)并最终在计算中使用该日期因此,性能是一个巨大的问题。

这是我到目前为止的想法,但它并没有让我得到我需要的地方:

SELECT
Type.TypeDesc
, Status.StatusDesc
, *
FROM
jw50_Item c
OUTER APPLY (SELECT TOP 10000 * FROM jw50_ItemLog csh WHERE csh.ItemID = c.ItemID AND csh.StatusCode = 'OPN' ORDER BY csh.AddDt DESC) [Status]
OUTER APPLY (SELECT TOP 10000 * FROM jw50_ItemLog cth WHERE cth.ItemID = c.ItemID AND cth.ItemTypeCode IN ('F','FG','NG','PF','SXA','AB') ORDER BY cth.AddDt DESC) Type
WHERE
c.ItemID = @ItemID

所以在下面提供的帮助下,我能够到达我需要的地方。这是我的最终解决方案:

SELECT 
OrderID
, CustomerNum
, OrderTitle
, ItemTypeDesc
, ItemTypeCode
, StatusCode
, OrdertatusDesc 
FROM 
    jw50_Order c1
    OUTER APPLY (SELECT TOP 1 [DateTime] FROM
                    (SELECT c.ItemTypeCode,     c.OrderStatusCode, c.OrderStatusDt as [DateTime] FROM jw50_Order c     WHERE c.OrderID = c1.OrderID
                    UNION
                    select (select top 1     c2.ItemTypeCode
                            from     jw50_OrderLog c2
                            where     c2.UpdatedDt >= c.UpdatedDt and c2.ItemTypeCode is not null and     c2.OrderID = c.OrderID
                            order by     UpdatedDt DESC
                           ) as type,
                           (select top 1     c2.StatusCode
                            from     jw50_OrderLog c2
                            where     c2.UpdatedDt >= c.UpdatedDt and c2.StatusCode is not null and     c2.OrderID = c.OrderID
                            order by     UpdatedDt DESC
                           ) as status,
                           UpdatedDt as     [DateTime]

                    from jw50_OrderLog c
                    where c.OrderID =     c1.OrderID AND (c.StatusCode IS NOT NULL OR c.ItemTypeCode IS NOT     NULL)
                    ) t
                    WHERE t.ItemTypeCode IN     ('F','FG','NG','PF','SXA','AB') AND t.StatusCode IN ('OPEN')
                    order by [DateTime]) quart
WHERE quart.DateTime <= @FiscalPeriod2 AND c1.StatusCode =     'OPEN'
Order By c1.OrderID

联合是为了创建结果集而引入除日志表数据之外的当前数据,因为当前数据可能满足所需的条件。再次感谢帮助人员。

2 个答案:

答案 0 :(得分:1)

这是一种使用相关子查询的方法:

select (select top 1 c2.type
        from jw50_Item c2
        where c2.AddDt >= c.AddDt and c2.type is not null
        order by AddDt
       ) as type,
       (select top 1 c2.status
        from jw50_Item c2
        where c2.AddDt >= c.AddDt and c2.status is not null
        order by AddDt
       ) as status,
       (select AddDt
from jw50_Item c

如果您在jw50_item(AddDt, type)jw50_item(AddDt, status)上有索引,那么效果应该非常好。

答案 1 :(得分:0)

我想您要“生成历史记录”:对于缺少某些数据的日期,应设置下一个可用数据。

类似的东西应该有效:

Select i.AddDt, t.Type, s.Status
from Items i
join Items t on (t.addDt = 
    (select min(t1.addDt) 
     from Items t1 
     where t1.addDt >= i.addDt 
       and t1.Type is not null))
join Items s on (s.addDt = 
    (select min(s1.addDt) 
      from Items s1 
     where s1.addDt >= i.addDt
       and s1.status is not null))

实际上我正在将基表连接到2个辅助表,并且连接条件是我们匹配辅助表中相应列不为空的最小行(当然小于当前日期)。

我不能确定它会起作用,因为我面前没有SQL Server但是试一试:)