有没有办法在同一个查询中重用子查询?
Is there a way to reuse subqueries in the same query?
请参阅问题末尾的更新以获取解决方案,感谢标记的答案!
我想将子查询视为可以在同一查询中重复使用的实际 table。这是设置 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);
我想要做的是 return 只有 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
它returns:
+----+---------------------------------+----------------------------+
| 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 |
+----+---------------------------------+----------------------------+
下一步是 return 每个 ID 仅最后一行。如果我要使用这个 SQL 将之前的 SELECT 写入 table...
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
它将return这样:
+----+------------+----------------------------+
| id | fieldvalue | ts |
+----+------------+----------------------------+
| 0 | hello | 2015-05-06 10:13:34.160000 |
| 1 | what up | 2015-05-06 10:13:35.470000 |
+----+------------+----------------------------+
如果我可以在初始 SELECT 中重用子查询,我可以获得相同的结果。我可以 copy/paste 整个查询 SQL 到另一个子查询中以创建派生的 table,但这只意味着我需要在两个地方更改 SQL 如果我曾经需要修改它。
更新
感谢 Kristján,我能够像这样在我的 SQL 中实现 WITH 子句以获得完美的结果:
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
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;
请参阅问题末尾的更新以获取解决方案,感谢标记的答案!
我想将子查询视为可以在同一查询中重复使用的实际 table。这是设置 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);
我想要做的是 return 只有 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
它returns:
+----+---------------------------------+----------------------------+ | 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 | +----+---------------------------------+----------------------------+
下一步是 return 每个 ID 仅最后一行。如果我要使用这个 SQL 将之前的 SELECT 写入 table...
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
它将return这样:
+----+------------+----------------------------+ | id | fieldvalue | ts | +----+------------+----------------------------+ | 0 | hello | 2015-05-06 10:13:34.160000 | | 1 | what up | 2015-05-06 10:13:35.470000 | +----+------------+----------------------------+
如果我可以在初始 SELECT 中重用子查询,我可以获得相同的结果。我可以 copy/paste 整个查询 SQL 到另一个子查询中以创建派生的 table,但这只意味着我需要在两个地方更改 SQL 如果我曾经需要修改它。
更新
感谢 Kristján,我能够像这样在我的 SQL 中实现 WITH 子句以获得完美的结果:
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
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;