检查同一 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
如果需要调整/更多详细信息,请发表评论。
我如何才能只检索在一个属性中具有子字符串的记录,该子字符串存在于同一属性中,但在同一 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
如果需要调整/更多详细信息,请发表评论。