检查同一 ID 的另一行中是否存在子字符串

check if a substring exists in another row for the same ID

我如何才能只检索在一个属性中具有子字符串的记录,该子字符串存在于同一属性中,但在同一 ID 的不同记录中?..

为了详细说明我的意思,这里有一个例子:

Table 包含两个属性:
- ID
- 版本

数据如下:

ID版本

1 'draft 1.0'
1 'final'
1 '1.0'
2 'draft 1.2'
2 'final'

在下面的示例中,我们看到对于 ID“1”,第一行的子字符串中包含“1.0”。对于 ID“1”,“1.0”值也出现在第三条记录中。至于 ID '2',版本 '1.2' 仅作为第四条记录中的子字符串。此 ID 本身没有包含版本号的记录。

我的目标是在 Oracle 中编写一个 SQL,它将 return 只有 ID“1”,因为它在不同的行中分别重复了版本

如有任何帮助,我们将不胜感激:)

拉米

这应该有效

with countOfVersion as
(select id, count(id) occurence
    from yourTable
    where regexp_like(version, '^*1.0$*$')
    group by id) select id from countOfVersion where occurence > 0;

如果您想检查版本 1.2,请不要忘记更改正则表达式中的 1.0。

根据您的解释,更好的建议可能是@mason 在评论中给出的建议:"You should normalize your tables.".

假设目前不是一个选项,我的第二个选项是添加一些包含版本号。至少这将使您能够轻松地为这些值编制索引以进行高效检索。我倾向于认为这也可以简化向适当架构的过渡:

ALTER TABLE T ADD "versnum"
              GENERATED ALWAYS AS (REGEXP_SUBSTR("version",'\d+(\.\d+)+'))
;

CREATE INDEX t_versnum_idx ON T("versnum")
;

现在,您的查询很简单:

select "ID", "versnum" from t group by "ID", "versnum" having count(*) > 1; 

制作中:

 id | versnum 
----+---------
  1 | 1.0 

如果您真的根本无法改变架构,使用 cte 可能是您最好的选择:

with cte as (
    select T.*, REGEXP_SUBSTR("version",'\d+(\.\d+)+') "versnum"
    from t
)   
select "ID", "versnum" from cte group by "ID", "versnum" having count(*) > 1;

一种不用正则表达式的方法:

SELECT
  T1.id
  , T1.version
FROM T T1
JOIN T T2
  ON T1.id = T2.id
AND INSTR(T2.version, T1.version) > 1
;

查看实际效果:SQL Fiddle
如果需要调整/更多详细信息,请发表评论。