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

问题描述 投票:1回答:3

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

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

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中实现吗?

sql oracle
3个回答
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;

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

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


0
投票

如果你加入pi_no字段,那么下面的加入应该有效。如果对于给定的pi_nosi_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;
© www.soinside.com 2019 - 2024. All rights reserved.