[英]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.