Oracle Listagg子查询

时间:2016-11-10 16:25:34

标签: sql oracle listagg

SELECT e.pem_id          AS id,
     e.pem_subject     AS subject,
     e.pem_content     AS content,
     e.pem_sent_date   AS sentdate,
     e.pem_ref_id      AS referenceid,
     e.pem_from_usr_id AS userid,
     NULL              AS misc,
     (listagg(str.str_us_id, ', ') within GROUP(ORDER BY '') AS attachedusers FROM
      proj_email_usrs eu LEFT OUTER JOIN st_register str ON
      eu.pmu_str_id = str.str_id WHERE eu.pmu_pem_id = '26' GROUP BY '')
FROM   proj_email e
WHERE  e.pem_prj_id = '33'
AND    e.pmu_pem_id = '26'
AND    e.pem_status = 'S';

正在抛出错误

  

ORA-01722:无效号码

     

01722。 00000 - “无效号码”

     

*原因:指定的号码无效。

     

*操作:指定有效数字。

1 个答案:

答案 0 :(得分:5)

我假设你想要这样的查询:

import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.BeforeAllCallback;
import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ContainerExtensionContext;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.api.extension.ParameterContext;
import org.junit.jupiter.api.extension.ParameterResolutionException;
import org.junit.jupiter.api.extension.ParameterResolver;
import org.junit.jupiter.api.extension.TestExtensionContext;
import org.springframework.restdocs.ManualRestDocumentation;

import java.lang.reflect.Method;
import java.util.Optional;

public class RestDocsExtension implements BeforeAllCallback, BeforeEachCallback, AfterEachCallback, ParameterResolver {

    private static final String REST_DOC_STORE_KEY = "restDocumentation";

    private ManualRestDocumentation restDocumentation;

    @Override
    public void beforeAll(ContainerExtensionContext context) throws Exception {
        if (restDocumentation == null) {
            restDocumentation = new ManualRestDocumentation("target/generated-snippets");
            getStore(context).put(REST_DOC_STORE_KEY, restDocumentation);
        }
    }

    @Override
    public void beforeEach(TestExtensionContext context) throws Exception {
        Optional<Class<?>> testClass = context.getTestClass();
        Optional<Method> methodNameOpt = context.getTestMethod();
        if (testClass.isPresent() && methodNameOpt.isPresent()) {
            getDoc(context).beforeTest(testClass.get().getClass(), methodNameOpt.get().getName());
        } else {
            throw new Exception("TestExtensionContext with no class or method. wat");
        }
    }

    @Override
    public void afterEach(TestExtensionContext context) throws Exception {
        getDoc(context).afterTest();
    }

    @Override
    public boolean supports(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
        return parameterContext.getParameter().getType() == ManualRestDocumentation.class;
    }

    @Override
    public Object resolve(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException {
        return getDoc(extensionContext);
    }

    private ManualRestDocumentation getDoc(ExtensionContext context) {
        return (ManualRestDocumentation) getStore(context).get(REST_DOC_STORE_KEY);
    }

    private ExtensionContext.Store getStore(ExtensionContext context) {
        return context.getStore(ExtensionContext.Namespace.DEFAULT);
    }
}

评论:

  • SELECT E.PEM_ID as Id, E.PEM_SUBJECT as Subject, E.PEM_CONTENT as Content, E.PEM_SENT_DATE as SentDate, E.PEM_REF_ID as ReferenceId, E.PEM_FROM_USR_ID as UserId, NULL as Misc, (SELECT LISTAGG(STR.STR_US_ID, ', ') WITHIN GROUP (ORDER BY STR.STR_US_ID) FROM PROJ_EMAIL_USRS EU LEFT OUTER JOIN ST_REGISTER STR ON EU.PMU_STR_ID = STR.STR_ID WHERE EU.PMU_PEM_ID = E.PMU_PEM_ID -- Correlation clause ) as AttachedUsers FROM PROJ_EMAIL E WHERE E.PEM_PRJ_ID = 33 AND E.PMU_PEM_ID = 26 AND E.PEM_STATUS = 'S' ; 之前添加了SELECT。需要子查询。
  • 删除LISTAGG()。不需要,因为您希望子查询始终返回一行。
  • 从可能是数字的常量中删除单引号。仅对字符串和日期常量使用单引号。
  • 在子查询中添加了关联子句。
  • 在子查询外移动了列的名称,因此在结果中命名。
  • GROUP BY添加了ORDER BY列。没有必要,但合理的是保持ids井井有条。