【问题标题】:MySQL SELECT following row with a different column valueMySQL SELECT 下一行具有不同的列值
【发布时间】:2017-05-15 06:03:05
【问题描述】:

我有一个这样的标签:

sn(char)   ts(int)     data(char) flag(tinyint)
'a'        1494825611  'a0'       1
'a'        1494825613  'a1'       0
'a'        1494825617  'a2'       0
'a'        1494825623  'a3'       1
'a'        1494825634  'a4'       1
'b'        1494825644  'b1'       1
'b'        1494825643  'b0'       0
'a'        1494825645  'a5'       1
'a'        1494825648  'a6'       0
'b'        1494825658  'b2'       1

行的顺序可能有误(如b1b0),因此应先按ts 排序。

我正在尝试对sn 进行有效查询,以获取当前和下一个flag 不同的行。

因此,我想为sn 'a' 提供类似的东西:

old_ts     ts         old_data data flag
1494825611 1494825613 'a0'     'a1' 0
1494825617 1494825623 'a2'     'a3' 1
1494825645 1494825648 'a5'     'a6' 0

对于sn'b'

old_ts     ts         old_data data flag
1494825643 1494825644 'b0',    'b1' 1

创建额外的列或表不是问题。

【问题讨论】:

  • 最后 2 行的 ts 是一样的 - 这是一个错字吗?
  • 是的,这是一个错字。已修复,谢谢!

标签: mysql sql select join


【解决方案1】:

您可以使用@rowFlag 变量。每行检查它是否等于标志。如果是,请将过滤器字段设置为 0 以稍后跳过它

select old_ts, ts, old_data, data, new_flag as flag
from
    (select
      t.ts,
      t.data,
      case when @rowFlag=flag then 0 else 1 end as filter,
      flag as new_flag,
      @rowFlag:=flag as old_flag,
      @old as old_data,
      @old:=data,
      @old_ts as old_ts,
      @old_ts:=ts
    from  test t, (select @rowFlag:=-1, @old:=null, @old_ts:=null) as def
    where sn='a'
    order by ts) as sub
where filter=1 and old_ts is not null;

SQL Fiddle

【讨论】:

  • 谢谢,看起来不错的解决方案,但这里有一个错误:(@rowFlag:=-1, :old=null)
  • 谢谢,还是报错:You have an error in your SQL syntax; ... use near ':old=null)
  • 还有一个问题 - Every derived table must have its own alias,我添加了 as def。但还有最后一个问题 - old_data 始终是 null
  • 这是一个错字。修复提交。请批准修复,我会接受您的回答。谢谢!
【解决方案2】:

您可以检查这个,因为它也包含旧值和新值。将 new_table 更改为您的实际表名。

select a.sn, a.ts as oldts, b.ts as newts, 
a.data as old_data, b.data as data, a.flag  as old_flag , b.flag as flag
from (
select sn, ts, data, flag , 
if(@oldSn = sn,@rowNumber := @rowNumber + 1,@rowNumber := 1) as row_number, 
@oldSn := sn as curentsn
from new_table
order by sn, ts ) a 
join  (
select sn, ts, data, flag , 
if(@oldSn1 = sn,@rowNumber := @rowNumber + 1,@rowNumber := 1) as row_number, 
@oldSn1 := sn as curentsn
from new_table
order by sn, ts ) b  on  a.sn = b.sn 
and a.row_number + 1 = b.row_number
where a.flag != b.flag

上述查询的输出

sn, oldts, newts, old_data, data, old_flag, flag
a, 1494825611, 1494825613, a0, a1, 1, 0
a, 1494825617, 1494825623, a2, a3, 0, 1
a, 1494825645, 1494825648, a5, a6, 1, 0
b, 1494825643, 1494825644, b0, b1, 0, 1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-25
    • 1970-01-01
    • 1970-01-01
    • 2017-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多