在子查询中访问外部查询列

时间:2017-10-13 03:50:33

标签: sql oracle

对于我们项目中的需求,我需要在Oracle SQL中将用户ID(连接字符串)转换为用户全名(连接字符串)。

示例:

Recipients
------------
R23198U,R324I98

输出:

Recipients
------------
Lonnie Lawson, Stan Smith

此"收件人"列来自表email_queue,并且Users表中提供了相应的用户全名。我不能在这里使用JOIN,因为这是两个不同的表,并且没有任何公共字段可以映射。

我在SQL下面尝试获取全名而不是user_name,但是它为所有行提供了相同的值。

我在SQL中执行这些任务

  1. 拆分user_names以从列表中获取单个值(使用正则表达式)
  2. 将每个user_name转换为full_name(来自users表)
  3. 将全名聚合为逗号分隔列表
  4. 下面是我的SQL:

    SELECT (SELECT Listagg(full_name, ',') 
                 within GROUP(ORDER BY full_name) AS CC_Recipients 
        FROM   (SELECT first_name 
                       ||' ' 
                       ||last_name AS full_name 
                FROM   users_table 
                WHERE  user_name IN (SELECT DISTINCT Trim(Regexp_substr( 
                                    cc_recipients, 
                                    '[^,]+', 1, 
                                                         LEVEL)) 
                                     FROM   dual 
                                     CONNECT BY Regexp_substr( 
                                                cc_recipients, 
                                                '[^,]+', 1, 
                                                LEVEL) IS 
                                                NOT NULL))t) AS cc_rec 
    FROM   email_queue 
    WHERE  cc_recipients IS NOT NULL; 
    

    查询结果:

    CC_REC                      CC_RECIPIENTS
    Lonnie Lawson,Stan Smith    R23198U,R324I98
    Lonnie Lawson,Stan Smith    R23198U
    Lonnie Lawson,Stan Smith    R23198U
    Lonnie Lawson,Stan Smith    R23198U
    

    请告诉我哪里出错了以及改进此代码的任何想法。

    由于

2 个答案:

答案 0 :(得分:0)

我只打印第一个名字,但我希望你能得到这个想法并轻松添加姓氏:

select Recipients,
       (select listagg(first_name, ', ') within group (order by first_name) from users_table where user_name in 
        ( select regexp_substr(eq.Recipients,'[^,]+', 1, level) 
          from dual 
          connect by regexp_substr(eq.Recipients, '[^,]+', 1, level) is not null  ) )
  from email_queue eq;

答案 1 :(得分:0)

您是否考虑过PL / SQL函数?将连接的用户ID作为输入参数,在函数内部解析它们,找到用户的全名并将它们连接起来。

我认为在一定规模上调整此解决方案的性能会更容易(如果生产系统上会有大量数据) - 最好记住这一点。