SQL 获取第一个匹配结果

Posted

技术标签:

【中文标题】SQL 获取第一个匹配结果【英文标题】:SQL get first matching results 【发布时间】:2012-06-25 19:37:40 【问题描述】:

我有以下 SQL 语句:

SELECT ID, NAME FROM myTable
WHERE 
ID LIKE 'R43%' OR 
ID LIKE 'D32%' OR 
ID LIKE 'F22%'

并且 ID 可能具有以下值:

ID
____

R431
R431
R432
R434
D322
D322
D327
F226
F227

如何仅获取匹配的第一个 ID 的记录?就像上面的值一样,我只会得到 (R431, R431, D322, D322, F226) 的记录。我从中获取的表中的 ID 值是连续的(因此 R432 将始终出现在表中的 R431 之后)。

【问题讨论】:

第一个匹配的 ID 是什么意思? 名称是否与 ID 相关联,因此 ID 为 R431 的所有记录都将具有相同的名称?这是一个细微的区别,但在排序和过滤时很重要。我认为答案在于使用 MAX 和 Group By 来获取正确的字段,但是如果没有关于表中确切架构的更多信息,很难猜测 group.order 的依据。在您有限的样本中,DISTINCT 会起作用,但我认为这不是您要问的。 @DavidCheung 我的意思是为“D32%”之类的搜索字符串找到的第一个 ID 值。因此,如果首先匹配“D322”,则只会返回 ID=D322 的记录 @DavidStratton 不,所有 id 的名称都可以是唯一的,所以我不能假设 R431 都具有相同的名称值 【参考方案1】:

对这类查询使用 Oracle 分析函数

    select * from (
select id , substr(id,0,3),rank() over ( partition by substr(id,0,3) order by id) rank 
from mytable
WHERE ID LIKE 'R43%' OR ID LIKE 'D32%' OR ID LIKE 'F22%')
where rank = 1

【讨论】:

我会将其更改为 PARTITION BY id。砍到 3 个字符是任意的。如果有R431156 id怎么办? 我使用 substr 因为 OP 只使用前 3 个字符来匹配 where 子句。 想知道如何在 Netezza 设备上为此执行 sn-ps。看起来您在这里遇到了全表扫描,如果性能开始出现问题,您也许可以进一步加快速度。【参考方案2】:

使用 DISTINCT:

SELECT DISTINCT ID, NAME FROM myTable
WHERE 
ID LIKE 'R43%' OR 
ID LIKE 'D32%' OR 
ID LIKE 'F22%'

【讨论】:

我不认为这符合他在此描述的:“就像上面的值一样,我只会获得 (R431, R431, D322, D322, F226) 的记录。” 这是基于我对他的要求的解释。我可能看错了。【参考方案3】:

一个 MIN 查询和一个嵌套子查询的组合应该可以得到你想要的。

Select ID, 
       Name 
FROM myTable 
WHERE 
     ID IN ( 
       SELECT MIN(ID) From myTable WHERE ID LIKE 'R43%' OR  ID LIKE 'D32%' OR  ID LIKE 'F22%'     
           )

如果您要关闭另一个字段,例如 OrderDate 等,请更改子查询。无论哪种方式,外部查询都只会从内部查询中选择的 ID 中选择记录。

【讨论】:

我不认为他在这里描述的那样:“就像上面的值一样,我只会获得 (R431, R431, D322, D322, F226) 的记录。” 根据上面的cmets编辑。【参考方案4】:

尝试使用子查询:

SELECT R.ID AS ID, R.NAME AS NAME FROM myTable R
WHERE 
R.ID LIKE 'R43%'
AND R.ID IN 
(
  SELECT DISTINCT A.ID
 FROM myTable A
 WHERE A.ID LIKE 'R43%'
 ORDER BY A.ID
 LIMIT 1
)

UNION 

SELECT D.ID AS ID, D.NAME AS NAME FROM myTable D
WHERE  
D.ID LIKE 'D32%'
AND D.ID IN 
(
  SELECT DISTINCT B.ID
 FROM myTable B
 WHERE B.ID LIKE 'D32%'
 ORDER BY B.ID
 LIMIT 1
)

UNION

SELECT F.ID AS ID, F.NAME AS NAME FROM myTable F
WHERE  
F.ID LIKE 'F22%'
AND F.ID IN 
(
  SELECT DISTINCT C.ID
 FROM myTable C
 WHERE C.ID LIKE 'F22%'
 ORDER BY C.ID
 LIMIT 1
)

【讨论】:

LIMIT 没有 ORDER BY 返回任意行。我认为他想要“第一”行,我假设它是以下之一:a)首先插入到表中的行 b)编号最小的行或 c)按字典顺序首先出现的行(OP不幸的是,他没有具体说明他想要这三个选项中的哪一个)。此外,如果您不必重复一大段代码n 次,那就更好了。

以上是关于SQL 获取第一个匹配结果的主要内容,如果未能解决你的问题,请参考以下文章

获取 SQL ANY 数组中每个元素的第一个匹配行

MySQL:从两个表中获取结果,在第三个中计算匹配项

SQL IN 子句仅返回以逗号分隔的 ID 列表中具有第一个匹配项的行

SQL 连接的补充?需要 T-SQL 帮助

如何在 SQL Server 中获取今天的第一个小时? [复制]

09 SQL语言——通配符(模糊查询),转义字符(使用escape)