将多个子查询从同一个表转换为一个查询

时间:2017-12-14 19:19:35

标签: sql oracle

这里我试图将三个不同的子查询从同一个表转换为一个子查询,这个子查询将分配到三个不同的列中。

可以吗? 我的实际查询是---

select p.pi_no,( SELECT pu_DATE
                 FROM tabl1
                 WHERE pi_no   = p.pi_no
                   AND si_no  = 45
               ) AS con_date,
               ( SELECT pu_DATE
                 FROM tabl1
                 WHERE pi_no   = p.pi_no
                   AND si_no     = 46
               ) AS subjvis,
               ( SELECT pu_DATE
                 FROM tabl1
                 WHERE pi_no   = p.pi_no
                   AND event_no     = 47
               ) AS initDate
from public p;

想要转换为这样的

select tu.pi_no, ( SELECT pu_DATE
                   FROM tabl1
                   WHERE pi_no   = tu.pi_no
                   AND si_no  IN( 45,46,47)
                 )
from public tu;

希望输出看起来像这样:

PI_NO || con_date(45) || subjvis(46) || initDate(47)
----------------------------------------
1234  || 14-DEC-2017 || 12-DEC-2017||15-DEC-2017    

这可以在oracle实现吗

3 个答案:

答案 0 :(得分:1)

我会用连接替换子查询

SELECT
    tu.pi_no,
    t1.pu_date AS con_date,
    t2.pu_date AS subjvis,
    t3.pu_date AS initDate
FROM
   public tu
   LEFT JOIN tabl1 t1 ON tu.pi_no = t1.pi_no AND t1.si_no = 45
   LEFT JOIN tabl1 t2 ON tu.pi_no = t2.pi_no AND t2.si_no = 46
   LEFT JOIN tabl1 t3 ON tu.pi_no = t3.pi_no AND t3.si_no = 47

您不能从选择列表中的子查询返回多个列。

答案 1 :(得分:1)

使用带有聚合函数MAX的条件逻辑来获取具有表格粒度的标量子查询值,PUBLIC

目标是返回对象的所有记录public(该名称不太理想,因为它是keyword)。由于对象的假定键PUBLICpi_no,因此我们将此列放在group by子句中,以确保查询的粒度相同。

我们使用条件逻辑的最大值来获取有值的记录(假设tabl1的键是pi_no, si_no)。

以下是解决方案:

SELECT
    p.pi_no,
    MAX(DECODE(si_no,45,t.pu_date,TO_DATE(NULL) ) ) con_date,
    MAX(DECODE(si_no,46,t.pu_date,TO_DATE(NULL) ) ) subjvis,
    MAX(DECODE(si_no,47,t.pu_date,TO_DATE(NULL) ) ) initdate
FROM
    public p
    LEFT OUTER JOIN tabl1 t ON pi_no = p.pi_no
                               AND si_no IN ( 45, 46, 37)
GROUP BY
    p.pi_no;

答案 2 :(得分:0)

如果您要加入pi_no字段,则下方加入应该有效。如果对于给定的pi_no,未找到si_no的特定值(即45),则将填充NULL。试试:

SELECT tu.pi_no,
CASE WHEN a.si_no = 45 THEN a.pu_DATE ELSE NULL END AS con_date,
CASE WHEN a.si_no = 46 THEN a.pu_DATE ELSE NULL END AS subjvis,
CASE WHEN a.si_no = 47 THEN a.pu_DATE ELSE NULL END AS initDate
FROM
PUBLIC tu
LEFT JOIN
tabl1 a
ON tu.pi_no = a.pi_no;