Похоже, вы соединяете первые две таблицы, например, с примерами данных, чтобы соответствовать тому, что вы показали в качестве вывода:
-- CTE for implied sample data
with family (num_family) as (
select 'FAM1' from dual
union all select 'FAM2' from dual
),
code (num_code) as (
select 'CODE1' from dual
union all select 'CODE2' from dual
union all select 'CODE3' from dual
)
-- actual query (edited from what you showed to be valid)
--SELECT t1.FAM,t2.CODE FROM (SELECT t1.FAM, t2.CODE FROM (SELECT num_family FROM family) t1, (SELECT num_code FROM code) t2)
SELECT t1.FAM, t2.CODE FROM (SELECT num_family as fam FROM family) t1, (SELECT num_code as code FROM code) t2
/
FAM CODE
---- -----
FAM1 CODE1
FAM1 CODE2
FAM1 CODE3
FAM2 CODE1
FAM2 CODE2
FAM2 CODE3
, который даже не нуждается в этих подзапросах, так же как и:
select f.num_family, c.num_code from family f cross join code c
и затем вы хотите получить количество совпадающих liste
значений в вашей таблице stats
, где в эту строку встроены значения как семейства, так и кода, перед которым стоит хеш:
Я должен сделать СЛУЧАЙ, КОГДА СПИСОК НРАВИТСЯ '% #' || t1.FAM || '%' THEN (СЛУЧАЙ, КОГДА ЛИСТ LIKE '% #' || t2.CODE || '%' THEN 1 ELSE 0 END) ELSE 0 END вместо SELECT COUNT (*) FROM stats
Вы можете делать то, что с внешним соединением и логической логикой в условии соединения, вместо того, чтобы пытаться использовать выражение case:
-- CTE for implied sample data
with family (num_family) as (
select 'FAM1' from dual
union all select 'FAM2' from dual
),
code (num_code) as (
select 'CODE1' from dual
union all select 'CODE2' from dual
union all select 'CODE3' from dual
),
stats (liste) as (
select 'abc #FAM1 def #CODE1 ghi' from dual connect by level <= 5
union all select 'jkl #CODE2#FAM1 mno' from dual connect by level <= 2
union all select '#FAM2#CODE1' from dual connect by level <= 9
union all select '#FAM2#CODE2' from dual connect by level <= 4
union all select '#FAM2#CODE3' from dual
union all select '#FAM2#CODE4' from dual -- no match
union all select '#FAM3#CODE1' from dual -- no match
)
-- actual query
select f.num_family, c.num_code, count(s.liste) as matches
from family f
cross join code c
left join stats s on s.liste like '%#'|| f.num_family ||'%'
and s.liste like '%#'|| c.num_code ||'%'
group by f.num_family, c.num_code
order by f.num_family, c.num_code;
NUM_ NUM_C MATCHES
---- ----- ----------
FAM1 CODE1 5
FAM1 CODE2 2
FAM1 CODE3 0
FAM2 CODE1 9
FAM2 CODE2 4
FAM2 CODE3 1
Шаблон like
будет проблематичным, если семейные или кодовые значения имеют перекрывающиеся корни или неожиданные частичные совпадения. Например. если бы у вас было liste
значений #FAM10#CODE20
, оно все равно совпадало бы с FAM1
и CODE2
. Вы можете переключиться на regexp_like()
, если сможете определить шаблон, чтобы избежать ложных совпадений (например, после пробела / пунктуации / EOL).