[英]A SQL puzzle (find the first occurrence of a column value)
CI有一种简单的方法可以找到列中具有特定值的行的第一次出现? 例如,假设我有这两个表
Alphabet
A
B
C
D
Alphabet Usage
A Apple
B Bat
D Dog
A Amateur
A Arsenal
C Cat
B Ball
D Drum
在第一个表中选择所有内容并在第二个表中选择它的第一次使用的简便方法是什么?
预期产量:
Alphabet Usage
A Apple
B Bat
C Cat
D Dog
您应该能够应用row_number()
。 但是,在使用row_number
时,需要提供一个顺序。
第一个例子通过使用顺序usage
,但问题是,不会在第一表中的顺序,这将是按字母顺序排列:
select alphabet, usage
from
(
select t1.alphabet,
t2.usage,
row_number() over(partition by t1.alphabet order by t2.usage) rn
from table1 t1
inner join table2 t2
on t1.alphabet = t2.alphabet
) src
where rn =1
请参阅带有演示的SQL Fiddle 。
如果您没有数字ID字段来保证第一个输入的顺序。 您可能可以使用:
select alphabet, usage
from
(
select t1.alphabet,
t2.usage,
row_number() over(partition by t1.alphabet order by (select 1)) rn
from table1 t1
inner join table2 t2
on t1.alphabet = t2.alphabet
) src
where rn =1
请参阅带有演示的SQL Fiddle 。
正如@Aaron在评论中指出的那样,使用此方法不能保证顺序,并且行为可以更改。
理想情况下,您应该具有一种排序类型的列,该列将使您能够区分数据的首次出现,即日期时间,ID等。由于表中的数据没有顺序,因此可以使用order by
来应用该顺序
您不能,除非您在第二张桌子上有订单。 SQL表本质上是无序的,因此您需要一列来指定插入时间或自动递增ID。
如果您碰巧正在运行没有并行性的SQL Server,并且数据存储在单个文件中,或者第二个表中的数据适合放在一页上,则以下方法可能会起作用(但不能保证):
select au.*
from (select au.Alphabet, min(seqnum) as minseqnum
from (select au.*, row_number() over (order by (select NULL)) as seqnum
from AlphabetUsage au
) au
group by au.Alphabet
) ausum join
(select au.*, row_number() over (order by (select NULL)) as seqnum
from AlphabetUsage au
) au
on ausum.seqnum = au.seqnum
根据我在SQL Server上的经验, row_number() over (order by (select NULL))
分配行号而不对数据进行排序。 但是,这没有记录并且不能保证。
我强烈建议您向表格中添加其他列,包括用于标识每一行的标识列。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.