【问题标题】:How can I left join on a field that is made up of a comma separated list如何在由逗号分隔的列表组成的字段上离开连接
【发布时间】:2024-04-15 02:05:01
【问题描述】:

我正在尝试根据获取层次结构路径的子查询中的字段,在逗号分隔值列表中加入表。我尝试将相关运算符连接到该值并在 in 子句中使用 in 它。连接是:

'('''||LTRIM(parent.path,''',')||''')'

当用作选择时,它会返回如下内容:

('VALUE1','VALUE2','VALUE2').

但是当我尝试在连接中使用它时:

left join table on id in ('('''||LTRIM(parent.path,''',')||''')')

它不起作用。

如果我将查询结果 ('VALUE1','VALUE2','VALUE2') 替换为公式,我会得到正确的结果。

任何帮助将不胜感激。

整个查询:

select '('''||LTRIM(parent.path,''',')||''')', dist.id, parent.*, opp.* 
from table1 opp
left join (
select connect_by_root(t1.id) as startpoint, connect_by_root(t1.parentid) as startparent,
t1.id as root_quote_id, SYS_CONNECT_BY_PATH(t1.id, ''',''') Path,LEVEL levels
from table2 t1
where connect_by_isleaf = 1
connect by prior t1.parentid = t1.id) parent on opp.distributor = parent.startpoint
left join table3 dist on dist.id in ('('''||LTRIM(parent.path,''',')||''')')
where startparent is not null

【问题讨论】:

  • 字符串是字符串,即使它包含逗号和单引号。这是错误的做法。一种想法是改用正则表达式。
  • 如果我将查询结果 ('VALUE1','VALUE2','VALUE2') 替换为公式,我会得到正确的结果。 - 您编写的查询像任何其他程序(带有标识符、关键字、值)一样编译。从来没有人能够说出SELECT * FROM t WHERE somecolumn IN '(my,list,of,values,in,a,string)'——当查询被编译成可执行形式时,它比能够说出select '* from mytable' 作为一个有效的查询更有意义。使其有效的唯一方法是构建一个作为查询的整个字符串并执行它(编译并运行它)
  • 这是一个非常常见的问题 - 搜索“IN 列表中的逗号分隔变量”或类似内容。但是,在您的情况下,要比较的值不会以逗号分隔的列表开始;您正在以这种格式将它们组装在一起。不要那样做;直接针对分层查询的结果写IN条件,不要使用分层路径!
  • (或者..在组装层次结构之前加入)

标签: sql oracle split left-join


【解决方案1】:

我同意评论者的观点,即最好的解决方案是重写您的查询。如果您提供一些示例数据和预期结果,我们或许可以提供帮助。

但是,如果您没有那么奢侈,解决问题的一个简单(且草率)的方法是将您的连接视为子字符串搜索。

left join table3 dist on parent.path||''',''' like '%,'''||dist.id||''',%'

如果您只使用单个字符作为 sys_connect_by_path 分隔符,这会更简单:

select parent.path||',', dist.id, parent.*, opp.* 
from table1 opp
left join (
    select connect_by_root(t1.id) as startpoint, connect_by_root(t1.parentid) as startparent,
    t1.id as root_quote_id, SYS_CONNECT_BY_PATH(t1.id, ',') Path, LEVEL levels
    from table2 t1
    where connect_by_isleaf = 1
    connect by prior t1.parentid = t1.id) parent 
        on opp.distributor = parent.startpoint
left join table3 dist on parent.path||',' like '%,'||dist.id||',%'
where startparent is not null

【讨论】:

    最近更新 更多