如何在 table 中为另一个 table 的每条记录查找特定行
How to find a specific row in a table for every record of another table
这就是 table 的样子 -
time id code
8/22/1999 12:00:00 AM 0001 A <------------ no
8/24/2001 6:03:02 AM 0001 A
6/27/2002 4:45:20 PM 0001 B
5/8/2003 9:03:13 AM 0001 B
5/8/2003 10:02:34 AM 0001 A <------------ no
6/9/2008 10:43:03 AM 0001 A
11/22/2011 3:42:10 PM 0001 A
4/11/2012 2:03:49 PM 0001 D
4/11/2012 2:04:00 PM 0001 D
12/6/2017 9:30:17 PM 0001 A <------------ yes
12/6/2017 9:30:17 PM 0001 A
12/6/2017 10:06:11 PM 0001 A
12/7/2017 3:24:58 AM 0001 C
1/3/2018 5:02:13 PM 0001 C
0001 是另一个 table 的 ID。 CODE 可以随时以任何顺序从 A 到 B 到 C 到 D 翻转。当代码从任何其他代码翻转到 A 时,我需要找到最近发生的事件。在此示例中,它发生在 "yes" 指示的行中。 "no" 记录无效,因为这种情况后来发生了。
不知道该怎么做。这可能需要一个存储过程,逐条记录,维护状态并计算出值。
编辑:
我想知道我是否可以以某种方式添加一个名为 grp 的列,就像这样 -
id code
A 1
A 1
B 2
B 2
A 3
A 3
A 3
D 4
D 4
A 5
A 5
A 5
C 6
C 6
那我就可以得到-
max of the min(grp) group by grp
假设这是 Sybase ASE,尽管以下大部分内容都相当简单 SQL 应该可以轻松转换为其他 RDBMS 产品
首先我们会看看是否可以找到 code
更改为 'A'
的 3 行
select f1.[time],
f1.id,
f1.code
from fliptable f1
where f1.code = 'A'
and ( -- see if the previous record has a code!='A'; to find the 'previous'
-- record we find the row with max(time) < current record's time
exists (select 1
from fliptable f2
where f2.id = f1.id
and f2.code != f1.code
and f2.[time] = (select max(f3.[time])
from fliptable f3
where f3.id = f1.id
and f3.[time] < f1.[time]))
or
-- catch case where the 'first' row in the table has code='A'
not exists (select 1
from fliptable f4
where f4.id = f1.id
and f4.[time] < f1.[time])
)
order by f1.[time]
go
time id code
------------------------------- ---- ----
Aug 22 1999 12:00AM 0001 A
May 8 2003 10:02AM 0001 A
Dec 6 2017 9:30PM 0001 A
Dec 6 2017 9:30PM 0001 A <=== side effect of having a dup row in the data
从这里我们应该可以添加一个 top 1
并翻转到 order by / desc
以拉取 last/newest 记录 ...
select top 1
f1.[time],
f1.id,
f1.code
from fliptable f1
where f1.code = 'A'
and ( exists (select 1
from fliptable f2
where f2.id = f1.id
and f2.code != f1.code
and f2.[time] = (select max(f3.[time])
from fliptable f3
where f3.id = f1.id
and f3.[time] < f1.[time]))
or
not exists (select 1
from fliptable f4
where f4.id = f1.id
and f4.[time] < f1.[time])
)
order by f1.[time] desc
go
time id code
------------------------------- ---- ----
Dec 6 2017 9:30PM 0001 A
在 ASE 15.7 SP138 上测试
这就是 table 的样子 -
time id code
8/22/1999 12:00:00 AM 0001 A <------------ no
8/24/2001 6:03:02 AM 0001 A
6/27/2002 4:45:20 PM 0001 B
5/8/2003 9:03:13 AM 0001 B
5/8/2003 10:02:34 AM 0001 A <------------ no
6/9/2008 10:43:03 AM 0001 A
11/22/2011 3:42:10 PM 0001 A
4/11/2012 2:03:49 PM 0001 D
4/11/2012 2:04:00 PM 0001 D
12/6/2017 9:30:17 PM 0001 A <------------ yes
12/6/2017 9:30:17 PM 0001 A
12/6/2017 10:06:11 PM 0001 A
12/7/2017 3:24:58 AM 0001 C
1/3/2018 5:02:13 PM 0001 C
0001 是另一个 table 的 ID。 CODE 可以随时以任何顺序从 A 到 B 到 C 到 D 翻转。当代码从任何其他代码翻转到 A 时,我需要找到最近发生的事件。在此示例中,它发生在 "yes" 指示的行中。 "no" 记录无效,因为这种情况后来发生了。
不知道该怎么做。这可能需要一个存储过程,逐条记录,维护状态并计算出值。
编辑:
我想知道我是否可以以某种方式添加一个名为 grp 的列,就像这样 -
id code
A 1
A 1
B 2
B 2
A 3
A 3
A 3
D 4
D 4
A 5
A 5
A 5
C 6
C 6
那我就可以得到-
max of the min(grp) group by grp
假设这是 Sybase ASE,尽管以下大部分内容都相当简单 SQL 应该可以轻松转换为其他 RDBMS 产品
首先我们会看看是否可以找到 code
更改为 'A'
select f1.[time],
f1.id,
f1.code
from fliptable f1
where f1.code = 'A'
and ( -- see if the previous record has a code!='A'; to find the 'previous'
-- record we find the row with max(time) < current record's time
exists (select 1
from fliptable f2
where f2.id = f1.id
and f2.code != f1.code
and f2.[time] = (select max(f3.[time])
from fliptable f3
where f3.id = f1.id
and f3.[time] < f1.[time]))
or
-- catch case where the 'first' row in the table has code='A'
not exists (select 1
from fliptable f4
where f4.id = f1.id
and f4.[time] < f1.[time])
)
order by f1.[time]
go
time id code
------------------------------- ---- ----
Aug 22 1999 12:00AM 0001 A
May 8 2003 10:02AM 0001 A
Dec 6 2017 9:30PM 0001 A
Dec 6 2017 9:30PM 0001 A <=== side effect of having a dup row in the data
从这里我们应该可以添加一个 top 1
并翻转到 order by / desc
以拉取 last/newest 记录 ...
select top 1
f1.[time],
f1.id,
f1.code
from fliptable f1
where f1.code = 'A'
and ( exists (select 1
from fliptable f2
where f2.id = f1.id
and f2.code != f1.code
and f2.[time] = (select max(f3.[time])
from fliptable f3
where f3.id = f1.id
and f3.[time] < f1.[time]))
or
not exists (select 1
from fliptable f4
where f4.id = f1.id
and f4.[time] < f1.[time])
)
order by f1.[time] desc
go
time id code
------------------------------- ---- ----
Dec 6 2017 9:30PM 0001 A
在 ASE 15.7 SP138 上测试