【问题标题】:Last non Null in a Pivot SQL queryPivot SQL 查询中的最后一个非 Null
【发布时间】:2013-01-15 20:28:05
【问题描述】:

我有下表,其中包含数据:

我有以下 sql 查询来操作数据,使用相同的 unix_timestamp 对所有数据进行分组以使用图形 api(时间线):

select * from 
                (
                    select unix_timestamp, date_time, input_raw, tag_id 
                    from [200030].[dbo].inputs
                    WHERE inputs.date_time > dateadd(day,-1,getdate())
                    AND
                    (tag_id = 92084 OR tag_id = 92106 OR tag_id = 92127 OR tag_id = 92149 OR tag_id = 92164 OR tag_id = 92193 OR tag_id = 92215)
                ) src
                pivot
                (
                    max(input_raw)
                    for tag_id in ([92084], [92106], [92127], [92149], [92164], [92193], [92215])
                ) piv
                ORDER by unix_timestamp DESC

它给了我这些结果(编号的列名来自原始表的 tag_id 字段:

这是很好的接受我需要从查询中再做一件事。我需要编号列下的条目是最后一个非 Null 值。除非没有以前的非空值。例如,92149 列下的第 4-8 行需要为 294 而不是 Null。

还有建议?

谢谢

【问题讨论】:

  • 请提供一些示例数据和期望的结果。
  • 这些列是否总是要被硬编码,或者您打算让它们动态化?
  • php 正在根据用户选择的 tag_ids 构建查询。只是 tag_id 部分
  • 样本数据很难给你。我从成千上万的 tag_id 中提取。不过我可以给你表格的结构。
  • 我有一个可以在列级别执行的递归 CTE,但我认为最有效的方法是简单地使用光标并从底部开始并返回。

标签: sql sql-server sql-server-2008-r2 pivot


【解决方案1】:

问题本质上是您在时间戳上“丢失”了数据,因为一次只有一个标签进入。一种方法是填写缺失的数据。

此查询获取时间戳和标签的所有组合,然后获取最新的 input_raw 值之前枢轴。该查询为此使用相关子查询。

                select unix_timestamp, date_time, tag_id,
                       coalesce(input_raw,
                                (select top 1 input_raw
                                 from inputs i
                                 where i.tag_id = tags.tag_id and
                                       i.unix_timestamp < tags.unix_timestamp
                                 order by unix_timestamp
                                )
                               ) as input_raw
                from (select 92084 as tag_id union all
                      select 92106 union all select 92127 union all select 92149 union all
                      select 92164 union all select 92193 union all select 92215
                     ) tags cross join
                     (select distinct unix_timestamp, datetime, input_raw
                      from [200030].[dbo].inputs
                      WHERE inputs.date_time > dateadd(day,-1,getdate())
                     ) t left outer join
                     [200030].[dbo].inputs i
                     on i.tag_id = tags.tag_id and
                        i.unix_timestamp = tags.unix_timestamp and
                        i.datetime = tags.datetime
                WHERE inputs.date_time > dateadd(day,-1,getdate())

这将替换您的内部子查询。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-29
    • 1970-01-01
    • 1970-01-01
    • 2014-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多