[英]A SQL puzzle (find the first occurrence of a column value)
CIs there an easy way where I can find the first occurrence of a row that has a particular value in a column? CI有一种简单的方法可以找到列中具有特定值的行的第一次出现? For example suppose I have these two tables
例如,假设我有这两个表
Alphabet
A
B
C
D
Alphabet Usage
A Apple
B Bat
D Dog
A Amateur
A Arsenal
C Cat
B Ball
D Drum
What would be an easy way to select everything in the first table and the first usage of it in the second table? 在第一个表中选择所有内容并在第二个表中选择它的第一次使用的简便方法是什么?
Expected Output: 预期产量:
Alphabet Usage
A Apple
B Bat
C Cat
D Dog
You should be able to apply row_number()
. 您应该能够应用
row_number()
。 However when using row_number
there is an order that needs to be provided. 但是,在使用
row_number
时,需要提供一个顺序。
This first example uses a order by usage
but the problem is that that will not be in the order of first in the table, it will be in alphabetical order: 第一个例子通过使用顺序
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
See SQL Fiddle with Demo . 请参阅带有演示的SQL Fiddle 。
If you do not have a numeric id field to guarantee the order of the first one entered. 如果您没有数字ID字段来保证第一个输入的顺序。 You might be able to use:
您可能可以使用:
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
See SQL Fiddle with Demo . 请参阅带有演示的SQL Fiddle 。
As @Aaron pointed out in the comments, that order is not guaranteed with using this method and the behavior can change. 正如@Aaron在评论中指出的那样,使用此方法不能保证顺序,并且行为可以更改。
Ideally, you should have sort type of column that will allow you distinguish the first occurrence of your data, ie datetime, id, etc. Since there is no order on data in a table, you apply the order using order by
理想情况下,您应该具有一种排序类型的列,该列将使您能够区分数据的首次出现,即日期时间,ID等。由于表中的数据没有顺序,因此可以使用
order by
来应用该顺序
You cannot, unless you have an ordering on the second table. 您不能,除非您在第二张桌子上有订单。 SQL Tables are inherently unordered, so you would need a column that specifies an insert time or an auto-incrementing id.
SQL表本质上是无序的,因此您需要一列来指定插入时间或自动递增ID。
If you happen to be running SQL Server with no parallelism and the data is stored in a single file or if the data in the second table fits on one page, then the following will probably work (but no guarantees): 如果您碰巧正在运行没有并行性的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
In my experience on SQL Server, row_number() over (order by (select NULL))
assigns a row number without ordering the data. 根据我在SQL Server上的经验,
row_number() over (order by (select NULL))
分配行号而不对数据进行排序。 However, this is not documented and not guaranteed. 但是,这没有记录并且不能保证。
I highly, highly recommend that you add additional columns to the table, including an identity column to identify each row. 我强烈建议您向表格中添加其他列,包括用于标识每一行的标识列。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.