【问题标题】:Referencing next and previous row values引用下一行和上一行值
【发布时间】:2015-01-25 10:32:08
【问题描述】:

我最近正在调查一个问题,即写入某个 dbs 表的行的百分比在不应为空的列中具有空值。当按时间戳列对该表进行排序时,我注意到具有空值的行不是随机分散的,而是大块的。该列有数千行为空,然后是数千行具有有效值,依此类推。

我想调查在这些波段的边界发生了什么,列从空值切换到非空值,反之亦然。在这些开关周围的时间或数据中找到模式似乎对调试问题非常有用。

我想不出让 sql 只选择这些行的方法,所以我最终编写了一个快速程序来处理数据并返回我想要的内容。请参阅下面的伪代码来演示该算法。

resultSet = db.query("select * from table t order by t.timestamp")
prevRow = null
// for simplicity, let's assume there's always at least 2 rows
currentRow = resultSet.next()
nextRow = resultSet.next()

while(resultSet.hasNext()) 

    // if the null state of column we care about has changed around this current row
    if(hasNullColumn(prevRow) != hasNullColumn(nextRow)) printRow(currentRow)   

    prevRow = currentRow;
    currentRow = nextRow; 
    nextRow = resultSet.next();

但是我真的很好奇是否有一种方法可以编写一个只返回上述逻辑打印的行的 sql 查询?那可能吗?

【问题讨论】:

  • LAGLEAD 函数,我相信它们是 SQL 的 ANSI 标准的一部分。 SQL Server 从 SQL Server 2012 开始支持这些功能。但不确定 MySQL(您标记了两者)。
  • 这个问题是关于 MySQL 还是 SQL-Server?它们不是一回事,请选择一个标签。

标签: mysql sql-server


【解决方案1】:

假设有一个唯一的 id 列,并且为了让事情变得有趣,它不会跟踪时间戳列的增加。还假设没有相等的时间戳。

select pt.* from
(Select max(ptime) as prevtime,min(ntime) as nextime from
((Select timestamp as ptime) as prev,
(Select timestamp as ntime) as next
where prev.ptime < next.ntime and prev.id<>next.id) as s1 group by ptime, ntime) as pn
inner join 
t as pt on pn.prevtime=pt.timestamp inner join 
t as nt on pn.nexttime=nt.timestamp
where pt.ncol!=nt.ncol;

解释:s1 提供了彼此之前和之后的时间对。 pn 将它们分组以获得所有相邻时间对的列表。 pt 在 pn 中提供上一次的其余列,而 nt 提供下一次的其余列。当我命名为 ncol 的列切换值时,前一行被吐出到结果集中。如果有多个非空值,并且只想找到空和非空之间的切换,那么将 pt.ncol!=nt.ncol 更改为 isnull(pt.ncol)!=isnull(nt.ncol)。

【讨论】:

    猜你喜欢
    • 2017-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多