SELECT 使用另一行数据的查询
SELECT query that uses data from another row
我有一个 table issue
结构如下:
+----+---------+-------------+------------+
| id | project | new_status | updated_at |
+----+---------+-------------+------------+
| 1 | 1 | New | 12:41:18 |
| 1 | 1 | In progress | 12:47:43 |
| 1 | 1 | Resolved | 17:05:29 |
+----+---------+-------------+------------+
我需要实现一个查询,即特定项目的每个问题在每个状态下花费的时间 returns,类似这样:
+----+---------+-------------+------------+
| id | project | new_status | time_diff |
+----+---------+-------------+------------+
| 1 | 1 | New | 00:06:25 |
| 1 | 1 | In progress | 04:17:46 |
+----+---------+-------------+------------+
我怎样才能得到这个?最好不要使用特殊的具体数据库特征,即只使用纯 SQL。但如果重要的话——我正在使用 PostgreSQL.
可能是一个简单的秒 table,包含项目 ID、步骤名称、开始时间和停止时间。对步骤进行排序的某种方式,例如简单的数字序列。然后 运行 在项目 ID 上的两个 table 之间进行连接,按步骤 ID 排序,并从结束时间中减去步骤的开始时间。用case语句表示当前步骤没有结束time.o
我临时写了这个查询,所以没有测试:
SELECT id, project, new_status, (updated_at - nextUpdate) AS time_diff
--or CAST((updated_at - nextUpdate) AS time) AS time_diff
FROM (
SELECT *,
LEAD(updated_at) OVER (PARTITION BY project ORDER BY updated_at) AS nextUpdate
FROM yourTable) dt
WHERE nextUpdate IS NOT NULL;
相关的答案是 this。
如果缺少下一步,则假设当前时间为您当前时区的当前时间:
SELECT *
FROM (
SELECT *, lead(updated_at, 1, now()::time(0)) OVER (PARTITION BY id, project
ORDER BY updated_at)
- updated_at AS time_diff
FROM issue
) sub
WHERE new_status <> 'Resolved' -- hide 'Resolved' row
ORDER BY updated_at;
您的示例显示 time
个值,这通常是一个有问题的选择。 (如果事件跨越多天怎么办?)改为考虑 timestamp
or timestamptz
。
如果没有下一行或上一行,window functions lead()
and lag()
可以提供默认值。我使用没有小数秒的当前时间。
由于您已经有了一些使用 lead() 函数(绝对是特定于数据库的函数)的示例,这里有一个不同的选项:http://sqlfiddle.com/#!15/497de/18
with t1 (id, project, new_status, updated_at, ndx) as (
select id, project, new_status, updated_at,
row_number() over (partition by id, project order by updated_at)
from issue
)
,
t2 (id, project, new_status, starttime, endtime) as (
select t1.id, t1.project, t1.new_status, t1.updated_at, t2.updated_at
from t1
left join t1 t2
on t2.id = t1.id
and t2.project = t1.project
and t2.ndx = t1.ndx + 1
)
,
t3 (id, project, new_status, time_diff) as (
select id, project, new_status, endtime - starttime
from t2
)
select id, project, new_status, to_char(time_diff, 'HH24:MI:SS') as time_diff
from t3
where time_diff is not null
此选项使用常见的 table 表达式为您的每个项目使用 row_number()
创建索引,然后根据该索引将 table 左连接到自身;即 t2.ndx = t1.ndx + 1
.
从那里开始,就是计算时间差异并将其格式化以显示的问题。
如果您想查看处于 'Resolved' 状态的问题已经过去了多少时间,那么如果 t2.updated_at
为空,则使用 coalesce(t2.updated_at,localtime)
之类的东西来获取当前时间.
我有一个 table issue
结构如下:
+----+---------+-------------+------------+
| id | project | new_status | updated_at |
+----+---------+-------------+------------+
| 1 | 1 | New | 12:41:18 |
| 1 | 1 | In progress | 12:47:43 |
| 1 | 1 | Resolved | 17:05:29 |
+----+---------+-------------+------------+
我需要实现一个查询,即特定项目的每个问题在每个状态下花费的时间 returns,类似这样:
+----+---------+-------------+------------+
| id | project | new_status | time_diff |
+----+---------+-------------+------------+
| 1 | 1 | New | 00:06:25 |
| 1 | 1 | In progress | 04:17:46 |
+----+---------+-------------+------------+
我怎样才能得到这个?最好不要使用特殊的具体数据库特征,即只使用纯 SQL。但如果重要的话——我正在使用 PostgreSQL.
可能是一个简单的秒 table,包含项目 ID、步骤名称、开始时间和停止时间。对步骤进行排序的某种方式,例如简单的数字序列。然后 运行 在项目 ID 上的两个 table 之间进行连接,按步骤 ID 排序,并从结束时间中减去步骤的开始时间。用case语句表示当前步骤没有结束time.o
我临时写了这个查询,所以没有测试:
SELECT id, project, new_status, (updated_at - nextUpdate) AS time_diff
--or CAST((updated_at - nextUpdate) AS time) AS time_diff
FROM (
SELECT *,
LEAD(updated_at) OVER (PARTITION BY project ORDER BY updated_at) AS nextUpdate
FROM yourTable) dt
WHERE nextUpdate IS NOT NULL;
相关的答案是 this。
如果缺少下一步,则假设当前时间为您当前时区的当前时间:
SELECT *
FROM (
SELECT *, lead(updated_at, 1, now()::time(0)) OVER (PARTITION BY id, project
ORDER BY updated_at)
- updated_at AS time_diff
FROM issue
) sub
WHERE new_status <> 'Resolved' -- hide 'Resolved' row
ORDER BY updated_at;
您的示例显示 time
个值,这通常是一个有问题的选择。 (如果事件跨越多天怎么办?)改为考虑 timestamp
or timestamptz
。
如果没有下一行或上一行,window functions lead()
and lag()
可以提供默认值。我使用没有小数秒的当前时间。
由于您已经有了一些使用 lead() 函数(绝对是特定于数据库的函数)的示例,这里有一个不同的选项:http://sqlfiddle.com/#!15/497de/18
with t1 (id, project, new_status, updated_at, ndx) as (
select id, project, new_status, updated_at,
row_number() over (partition by id, project order by updated_at)
from issue
)
,
t2 (id, project, new_status, starttime, endtime) as (
select t1.id, t1.project, t1.new_status, t1.updated_at, t2.updated_at
from t1
left join t1 t2
on t2.id = t1.id
and t2.project = t1.project
and t2.ndx = t1.ndx + 1
)
,
t3 (id, project, new_status, time_diff) as (
select id, project, new_status, endtime - starttime
from t2
)
select id, project, new_status, to_char(time_diff, 'HH24:MI:SS') as time_diff
from t3
where time_diff is not null
此选项使用常见的 table 表达式为您的每个项目使用 row_number()
创建索引,然后根据该索引将 table 左连接到自身;即 t2.ndx = t1.ndx + 1
.
从那里开始,就是计算时间差异并将其格式化以显示的问题。
如果您想查看处于 'Resolved' 状态的问题已经过去了多少时间,那么如果 t2.updated_at
为空,则使用 coalesce(t2.updated_at,localtime)
之类的东西来获取当前时间.