2015-05-06 45 views
1

请参阅更新在问题结束时为解决方案感谢标记答案!有没有办法在同一个查询中重用子查询?

我想对待一个子查询,就好像它是一个可以在相同查询中重用的实际表一样。下面是安装SQL:

create table mydb.mytable 
(
    id integer not null, 
    fieldvalue varchar(100), 
    ts timestamp(6) not null 
) 
unique primary index (id, ts) 

insert into mydb.mytable(0,'hello',current_timestamp - interval '1' minute); 
insert into mydb.mytable(0,'hello',current_timestamp - interval '2' minute); 
insert into mydb.mytable(0,'hello there',current_timestamp - interval '3' minute); 
insert into mydb.mytable(0,'hello there, sir',current_timestamp - interval '4' minute); 
insert into mydb.mytable(0,'hello there, sir',current_timestamp - interval '5' minute); 
insert into mydb.mytable(0,'hello there, sir. how are you?',current_timestamp - interval '6' minute); 

insert into mydb.mytable(1,'what up',current_timestamp - interval '1' minute); 
insert into mydb.mytable(1,'what up',current_timestamp - interval '2' minute); 
insert into mydb.mytable(1,'what up, mr man?',current_timestamp - interval '3' minute); 
insert into mydb.mytable(1,'what up, duder?',current_timestamp - interval '4' minute); 
insert into mydb.mytable(1,'what up, duder?',current_timestamp - interval '5' minute); 
insert into mydb.mytable(1,'what up, duder?',current_timestamp - interval '6' minute); 

我想要做的是只返回行,其中FieldValue从以前的行不同。这个SQL做到了这一点:

locking row for access 
select id, fieldvalue, ts from 
(
    --locking row for access 
    select 
     id, fieldvalue, 
     min(fieldvalue) over 
     (
      partition by id 
      order by ts, fieldvalue rows 
      between 1 preceding and 1 preceding 
     ) fieldvalue2, 
     ts 
    from mydb.mytable 
) x 
where 
    hashrow(fieldvalue) <> hashrow(fieldvalue2) 
order by id, ts desc 

它返回:

+----+---------------------------------+----------------------------+ 
| id |   fieldvalue   |    ts    | 
+----+---------------------------------+----------------------------+ 
| 0 | hello       | 2015-05-06 10:13:34.160000 | 
| 0 | hello there      | 2015-05-06 10:12:34.350000 | 
| 0 | hello there, sir    | 2015-05-06 10:10:34.750000 | 
| 0 | hello there, sir. how are you? | 2015-05-06 10:09:34.970000 | 
| 1 | what up       | 2015-05-06 10:13:35.470000 | 
| 1 | what up, mr man?    | 2015-05-06 10:12:35.690000 | 
| 1 | what up, duder?     | 2015-05-06 10:09:36.240000 | 
+----+---------------------------------+----------------------------+

下一步是每个ID只返回了最后一排。如果我用这个SQL写的前一个选择到表...

create table mydb.reusetest as (above sql) with data; 

......然后我可以做到这一点做得到每个ID的最后一行:

locking row for access 
select t1.* from mydb.reusetest t1, 
(
    select id, max(ts) ts from mydb.reusetest 
    group by id 
) t2 
where 
    t2.id = t1.id and 
    t2.ts = t1.ts 
order by t1.id 

会返回这个:

+----+------------+----------------------------+ 
| id | fieldvalue |    ts    | 
+----+------------+----------------------------+ 
| 0 | hello  | 2015-05-06 10:13:34.160000 | 
| 1 | what up | 2015-05-06 10:13:35.470000 | 
+----+------------+----------------------------+

如果我可以在我的初始SELECT中重用子查询,我可以实现相同的结果。我可以将整个查询SQL复制/粘贴到另一个子查询中以创建派生表,但这意味着如果需要修改它,我需要在两处更改SQL。

更新

感谢克里斯蒂安,我是能够实现WITH子句到我的SQL像这样完美的结果:

locking row for access 
with items (id, fieldvalue, ts) as 
(
    select id, fieldvalue, ts from 
    (
     select 
      id, fieldvalue, 
      min(fieldvalue) over 
      (
       partition by id 
       order by ts, fieldvalue 
       rows between 1 preceding and 1 preceding 
      ) fieldvalue2, 
      ts 
     from mydb.mytable 
    ) x 
    where 
     hashrow(fieldvalue) <> hashrow(fieldvalue2) 
) 
select t1.* from items t1, 
(
    select id, max(ts) ts from items 
    group by id 
) t2 
where 
    t2.id = t1.id and 
    t2.ts = t1.ts 
order by t1.id 

回答

1

是否WITH帮助?这可让您定义可在SELECT中多次使用的结果集。

从他们的例子:

WITH orderable_items (product_id, quantity) AS 
(SELECT stocked.product_id, stocked.quantity 
    FROM stocked, product 
    WHERE stocked.product_id = product.product_id 
    AND product.on_hand > 5 
) 

SELECT product_id, quantity 
FROM orderable_items 
WHERE quantity < 10; 
+0

这完美的作品。在我的答案结尾处查看解决方案。谢谢! – oscilatingcretin

相关问题