SQL获取子字符串列表然后用作LI​​KE的值

时间:2016-03-22 14:54:42

标签: sql oracle substring

我想使用子字符串列表作为id name ------------------------------------------------------- 562 B6;129 (Bnip3 KO) 563 B6;129 (BNIP3 Wt) [pregnant] 564 B6;129 (BNIP3 Wt) [older than 21 days] 720 BALB/C T(x:11)38H (T38H) 721 BALB/C [older than 21 days] 子句的值。

考虑以下表格:

菌株

id    protocol_id     strain_id
-------------------------------------------------------
1     61846           563
2     13487           564
3     79465           721
4     41699           720

链接(l)

id    group_id        strain_id
-------------------------------------------------------
24    9666            563
25    9666            720

动物(a)

group_id

通常我会提供一个我尝试过的查询,但这次我什么都没有。相反,让我分解我需要做的步骤:

  1. 从相同(下的所有动物的菌株名称中获取子串列表。
    • 要获取子字符串,我想要)SELECT /* get the list of substrings */ FROM animals a LEFT JOIN strains s ON s.id = a.strain_id WHERE a.group_id = 9666
    • 中的字符串
    • (BNIP3 Wt)
    • 之类的东西
    • 在此示例中,我需要以下列表:(T38H)(
    • 如果)LIKE中包含多个值,请使用最后一个
  2. 使用上面的结果列表获取protocol_id子句,以获取其应变名称包含子字符串的SELECT l.protocol_id FROM links l LEFT JOIN strains s ON s.id = l.strain_id WHERE s.name LIKE (/* put the list here with the % for wildcards */) 列表。
  3. 我对解决方案的想法

    protocol_id
    ------------------------------
    61846
    13487
    41699
    

    我想得到的最终结果如下:

    {{1}}

2 个答案:

答案 0 :(得分:1)

SQL Fiddle

Oracle 11g R2架构设置

CREATE TABLE Strains (id, name ) AS
SELECT 562,   'B6;129 (Bnip3 KO)' FROM DUAL UNION ALL
SELECT 563,   'B6;129 (BNIP3 Wt) [pregnant]' FROM DUAL UNION ALL
SELECT 564,   'B6;129 (BNIP3 Wt) [older than 21 days]' FROM DUAL UNION ALL
SELECT 720,   'BALB/C T(x:11)38H (T38H)' FROM DUAL UNION ALL
SELECT 721,   'BALB/C [older than 21 days]' FROM DUAL;

CREATE TABLE Links (id, protocol_id, strain_id ) AS
SELECT 1,     61846,           563 FROM DUAL UNION ALL
SELECT 2,     13487,           564 FROM DUAL UNION ALL
SELECT 3,     79465,           721 FROM DUAL UNION ALL
SELECT 4,     41699,           720 FROM DUAL;

CREATE TABLE Animals (id, group_id, strain_id ) AS
SELECT 24,    9666,            563 FROM DUAL UNION ALL
SELECT 25,    9666,            720 FROM DUAL;

查询1

SELECT l.protocol_id
FROM   links l
       INNER JOIN strains s
       ON s.id = l.strain_id
       INNER JOIN (
         SELECT REGEXP_SUBSTR( s.name, '\(.*?\)', 1, l.COLUMN_VALUE ) AS id
         FROM   strains s,
                TABLE( 
                  CAST(
                    MULTISET(
                      SELECT LEVEL
                      FROM   DUAL
                      CONNECT BY LEVEL <= REGEXP_COUNT( s.name, '\(.*?\)' )
                    ) AS SYS.ODCINUMBERLIST
                  )
                ) l,
                animals a
         WHERE  a.strain_id = s.id
         AND    a.group_id = 9666
       ) t
       ON s.name LIKE '%' || t.id || '%'

<强> Results

| PROTOCOL_ID |
|-------------|
|       61846 |
|       13487 |
|       41699 |
|       41699 |

答案 1 :(得分:0)

您可以使用REGEXP_LIKE

解决问题

e.g。

With strains (id, name) as
(
          select 562,   'B6;129 (Bnip3 KO)' from dual
union all select 563,   'B6;129 (BNIP3 Wt) [pregnant]'  from dual
union all select 564,   'B6;129 (BNIP3 Wt) [older than 21 days]'  from dual
union all select 720,   'BALB/C T(x:11)38H (T38H)'  from dual
union all select 721,   'BALB/C [older than 21 days]'  from dual
)
    ,Links (id, protocol_id, strain_id ) as
(    
          select 1,     61846,           563 from dual
union all select 2,     13487,           564 from dual
union all select 3,     79465,           721 from dual
union all select 4,     41699,           720 from dual
)
   ,Animals (id, group_id, strain_id) as
(   
          select 24,    9666,            563 from dual
union all select 25,    9666,            720 from dual
)
SELECT l.protocol_id
FROM links l
LEFT JOIN strains s ON s.id = l.strain_id
WHERE  REGEXP_LIKE (s.name, '*BNIP3|T38H*');