根据某些条件在选择中需要附加的行

时间:2019-01-07 14:19:45

标签: sql oracle

我有一个表,其中包含列:attribute_1,attribute_2,org_name,国家/地区

attribute_1  attribute_2  org_name  country
wcc_4599        null        org1     IN
wcc_0123        wcc_1983    org2     IN
wcc_2390        null        org3     US
wcc_5647        wcc_8789    org4     IN

我的要求是:

  1. 根据以下条件,我必须确定document_type

         (i) if country  = India , attribute_1 != null, attribute_2  = null THEN Document Type ==> PAN
        (ii) if country  = India , attribute_1 != null, attribute_2 != null THEN Document Type ==> PAN , PROPRIETORSHIP DOCUMNENT
       (iii) if country != India , attribute_1 != null, attribute_2  = null THEN Document Type ==> COMPANY REGISTRAION DOCUMENT
    
  2. 对于情况(ii),我需要为每条记录显示两行,第一行显示attribute_1,第二行显示attribute_2

我有以下查询

SELECT   
     attribute_1,
     attribute_2,
     upper(org_name) org_name,                      
     country,
CASE
    WHEN country = 'IN'
         AND attribute_1 IS NOT NULL
         AND attribute_2 IS NULL THEN 'PAN'
    WHEN country = 'IN'
         AND attribute_1 IS NOT NULL
         AND attribute_2 IS NOT NULL THEN 'PAN , PROPRIETORSHIP DOCUMNENT'
    WHEN country != 'IN'
         AND attribute_1 IS NOT NULL
         AND attribute_2 IS NULL THEN 'COMPANY REGISTRAION DOCUMENT'     
END
doc_name
            FROM
                tbl_1
            ORDER BY
                created_date_time;

输出:

attribute_1  attribute_2  org_name  country doc_type
wcc_4599        null        org1     IN      PAN
wcc_0123        wcc_1983    org2     IN      PAN, PROPRIETORSHIP DOCUMENT
wcc_2390        null        org3     US      COMPANY REGISTRAION DOCUMENT
wcc_5647        wcc_8789    org4     IN      PAN, PROPRIETORSHIP DOCUMENT

但是我需要像这样的输出:

attribute_1_2  org_name country doc_type
wcc_4599        org1     IN      PAN
wcc_0123        org2     IN      PAN
wcc_1983        org2     IN      PROPRIETORSHIP DOCUMENT
wcc_2390        org3     US      COMPANY REGISTRAION DOCUMENT
wcc_5647        org4     IN      PAN
wcc_8789        org4     IN      PROPRIETORSHIP DOCUMENT

目前,我已经创建了一个过程来获取所需的输出。但是我想通过查询来做到这一点。有可能吗?

谢谢!

2 个答案:

答案 0 :(得分:1)

使用nvl2将行标记为2行类型的1行。然后使用unpivot,它将在删除null的同时生成所需的行。最后一步是根据业务逻辑分配适当的doc_type

dbfiddle demo

select attr, upper(org_name) org, country, 
       case when (rws = 1 and country = 'IN') or (rws = 2 and val = 'A1') then 'PAN'
            when rws = 1 then 'COMPANY REGISTRATION DOCUMENT' 
            else 'PROPRIETORSHIP DOCUMENT'
       end doc_type
  from (
    select * 
      from (select tbl_1.*, nvl2(attribute_2, 2, 1) rws from tbl_1) t
      unpivot (attr for val in (attribute_1 as 'A1', attribute_2 as 'A2')))

结果:

ATTR     ORG  COUNTRY DOC_TYPE
-------- ---- ------- -----------------------------
wcc_4599 ORG1 IN      PAN
wcc_0123 ORG2 IN      PAN
wcc_1983 ORG2 IN      PROPRIETORSHIP DOCUMENT
wcc_2390 ORG3 US      COMPANY REGISTRATION DOCUMENT
wcc_5647 ORG4 US      PAN
wcc_8789 ORG4 US      PROPRIETORSHIP DOCUMENT
6 rows selected

unpivot在Oracle 11g或更高版本中可用。在较旧的版本中,您可以使用union all或通过加入映射表来实现。

编辑: union all查询,可能更具可读性:

select attribute_1 attr, upper(org_name) org, country,
       case when country = 'IN' or attribute_2 is not null then 'PAN'
            else 'COMPANY REGISTRATION DOCUMENT'
       end doc_type
  from tbl_1
union all
select attribute_2 attr, upper(org_name) org, country, 'PROPRIETORSHIP DOCUMENT'
  from tbl_1
  where attribute_2 is not null

答案 1 :(得分:0)

我认为这里缺少一张表,该表可以将CASE表达式的标量输出映射到一个或多个行。考虑使用以下CTE,并将您当前的查询放入CTE:

WITH doc_type AS (
    SELECT 1 AS id, 'PAN' AS type FROM dual UNION ALL
    SELECT 2, 'PAN' FROM dual UNION ALL
    SELECT 2, 'PROPRIETORSHIP DOCUMNENT' FROM dual UNION ALL
    SELECT 3, 'COMPANY REGISTRAION DOCUMENT' FROM dual
),
cte AS (
    SELECT
        attribute_1,
        attribute_2,
        UPPER(org_name) org_name,
        country,
        created_date_time
    CASE WHEN country = 'IN' AND
              attribute_1 IS NOT NULL AND
              attribute_2 IS NULL THEN 1
         WHEN country = 'IN' AND
              attribute_1 IS NOT NULL AND
              attribute_2 IS NOT NULL THEN 2
         WHEN country != 'IN' AND
              attribute_1 IS NOT NULL AND
              attribute_2 IS NULL THEN 3 END AS doc_id
    FROM tbl_1
)

现在,我们可以从CASE表达式中加入您当前的计算列,以生成您期望的记录:

SELECT
    t1.attribute_1,
    t1.attribute_2,
    t1.org_name,
    t1.country,
    t2.type
FROM cte t1
INNER JOIN doc_type t2
    ON t1.doc_id = t2.id
ORDER BY
    t1.created_date_time;