SQL 基于另一个 table 的查询

SQL query based on another table

我有 table 个这样的:

table 1:

FNAME ID1 FID
BREAD XYZ 18BREAD
FISH ABC 45FISH
BREAD_OLD BNQ 18BREAD_OLD
BACON TBG 77BACON
EGGS CGS 99EGGS
BANANA BHG BANANA18

table 2:

FNAME FID
BREAD 18
FISH 45
BACON 77
EGGS 99

目前在 table 1 上进行了一个简单的搜索,以查找食物的 id,如下所示:

SELECT ID1 
FROM TABLE1
WHERE NAME IN NAME_LIST

例如,当名单是:('BREAD','FISH') 那么它是 returns XYZ, ABC。问题是这遗漏了 'BREAD_OLD',它是具有相同 ID 的旧版本。 (18)

我需要更改此设置,因此现在搜索是基于食物的 FID 而不是 NAME 来查找受影响的食物,但我无法更改输入。

例如:给定一份食物清单:('BREAD', 'FISH')

结果应为 XYZ、ABC、BNQ(因为 BREAD 匹配 18 匹配 table 1 中的 BNQ)

这怎么能做到?我想我需要使用连接或执行 'select within a select',但我不确定这将如何处理多个输入。

编辑:ORACLE 是数据库 编辑 2:将 BANANA18 添加到 table 1,需要领先匹配

正确的解决方案是 link FID 字段。但是,table1 上的 FID 字段似乎将 ID 与名称连接在一起。因此,解决方案是从该字段中提取数值,然后将其用于 link 到 table 2 上的 FID 字段。例如:

SELECT t1.FNAME, t1.ID1
FROM table1 t1 
INNER JOIN table2 t2 ON t2.FID = regexp_replace(t1.FID, '^[^0-9]', '')
WHERE 
t2.FNAME IN ('BREAD','FISH');

示例数据:

SELECT * FROM TABLE1;

FNAME     ID1   FID
-------------------------
BREAD     XYZ   18BREAD
FISH      ABC   45FISH 
BACON     TBG   77BACON
EGGS      CGS   99EGGS 
BREAD_OLD BNQ   18BREAD_OLD

SELECT * FROM TABLE2;

FNAME  FID
----------
BREAD   18
FISH    45
BACON   77
EGGS    99

查询:

在查询中,我们在 FID 上连接 TABLE1 和 TABLE2(使用 REGEX_SUBSTR 提取 TABLE1 FID 的前 n 个数字),因此行 'BREAD_OLD' 将与 TABLE2 中的行 'BREAD' 连接,并且当我们添加条件 FNAME IN ('BREAD') 时,'BREAD' 和 'BREAD_OLD' 的 ID1 都将被选中。

SELECT ID1
FROM
(SELECT
TO_NUMBER(REGEXP_SUBSTR(FID,'^[0-9]{1,}'),'9999') AS FID,FNAME,ID1
FROM TABLE1)V
JOIN TABLE2 T
ON (V.FID=T.FID)
WHERE T.FNAME IN ('BREAD','FISH')

结果:

ID1
---
XYZ
ABC
BNQ

一个选项是通过将 table2 的串联列与提取的子字符串匹配到 fid 列的 _ 个字符来连接表table1 比如

 SELECT id1
   FROM table1 t1
   JOIN table2 t2
     ON REGEXP_SUBSTR(t1.fid,'[^_]+') = t2.fid||t2.fname
  WHERE t2.fname IN ('BREAD','FISH')

Demo

假设 table1.FID 等于 table2.FIDtable1.FNAME 连接,那么您不需要(慢速)正则表达式,可以使用简单的等式与字符串连接相结合:

SELECT t1.FNAME,
       t1.ID1
FROM   table1 t1 
       INNER JOIN table2 t2
       ON t1.FID = t2.fid || t1.fname
WHERE  t2.FNAME IN ('BREAD','FISH');

其中,对于示例数据:

CREATE TABLE table1 (FNAME, ID1, FID) AS
SELECT 'BREAD',     'XYZ', '18BREAD'  FROM DUAL UNION ALL
SELECT 'FISH',      'ABC', '45FISH'   FROM DUAL UNION ALL
SELECT 'BREAD_OLD', 'BNQ', '18BREAD_OLD' FROM DUAL UNION ALL
SELECT 'BACON',     'TBG', '77BACON'  FROM DUAL UNION ALL
SELECT 'EGGS',      'CGS', '99EGGS'   FROM DUAL UNION ALL
SELECT 'BANANA',    'BHG', 'BANANA18' FROM DUAL UNION ALL
SELECT 'TOAST',     'TST', 'TOAST181' FROM DUAL;

CREATE TABLE table2 (FNAME, FID) AS
SELECT 'TOAST', 181 FROM DUAL UNION ALL
SELECT 'BREAD',  18 FROM DUAL UNION ALL
SELECT 'FISH',   45 FROM DUAL UNION ALL
SELECT 'BACON',  77 FROM DUAL UNION ALL
SELECT 'EGGS',   99 FROM DUAL;

输出:

FNAME ID1
BREAD XYZ
BREAD_OLD BNQ
FISH ABC

db<>fiddle here