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')
假设 table1.FID
等于 table2.FID
与 table1.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
我有 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')
假设 table1.FID
等于 table2.FID
与 table1.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