【问题标题】:More than one row returns oracle多行返回oracle
【发布时间】:2020-10-08 12:33:23
【问题描述】:

我有一张如下所示的表格:

tbl_phone

id  clnt_cd   phone_type   Phone_no
__  ________  __________  __________
1   12345       R          09030102
2   67891       B          043-2020
3   27282       M          09030301
4   12345       M          08202021

tbl_client

clnt_cd   first_name    last_name
_______   ___________   _________
12345      Eren         Jaeger
67891      Mikasa       Jaeger

我在 oracle 中有这样的脚本:

SELECT tc.first_name, tc.last_name, (SELECT FROM tbl_phone WHERE phone_type = 'R' ) AS "Residence Telephone Number", (SELECT FROM tbl_phone WHERE phone_type = 'B') AS "Office Telephone Number", (SELECT FROM tbl_phone WWHERE phone_type = 'M') AS "Cellphone Number" FROM tbl_client tc INNER JOIN tbl_phone tp ON tc.clnt_cd = TP.clnt_cd

问题是错误总是显示 ORA-01427: Single-row subquery returns more than one row.

我想要得到的输出是

clint_cd  first_name  last_name  residence telephone number  Office telephone number  cellphone number
________  __________  _________  __________________________  _______________________  ________________
12345      Eren         Jaeger     09030102                    N/A                      08202021
67891      Mikasa       Jaeger     N/A                         043-2020                 N/A

【问题讨论】:

  • 每种电话号码类型左加入一次,

标签: sql oracle


【解决方案1】:

改为使用条件聚合:

select *
from tbl_client c join
     (select p.clnt_cd,
             max(case when phone_type = 'R' then Phone_no end) as r_phone,
             max(case when phone_type = 'B' then Phone_no end) as b_phone,
             max(case when phone_type = 'M' then Phone_no end) as m_phone
      from tbl_phone p
      group by p.clnt_cd
     ) p
     using (clnt_cd);

【讨论】:

  • 嗨!想问一下如果inner join里面有很多表怎么办?
  • @ElijahLeis。 . .这回答了您在此处提出的问题,该问题专门针对两个表。我认为添加额外的joins 没有问题,但如果这是个问题,请提出 问题。
  • 已经提出另一个问题:stackoverflow.com/questions/64263647/…
【解决方案2】:

使用PIVOT

SELECT c.*,
       p.residence_phone_no,
       p.business_phone_no,
       p.cellphone_phone_no
FROM   tbl_client c
       LEFT OUTER JOIN (
         SELECT *
         FROM   (
           SELECT p.clnt_cd,
                  p.phone_type,
                  p.phone_no
           FROM   tbl_phone p
         )
         PIVOT (
           MAX( phone_no ) FOR phone_type IN (
             'R' AS residence_phone_no,
             'B' AS business_phone_no,
             'M' AS cellphone_phone_no
           )
         )
       ) p
       ON ( c.clnt_cd = p.clnt_cd )

其中,对于您的示例数据:

CREATE TABLE tbl_phone ( id, clnt_cd, phone_type, Phone_no ) AS
SELECT 1,   12345,       'R',          '09030102' FROM DUAL UNION ALL
SELECT 2,   67891,       'B',          '043-2020' FROM DUAL UNION ALL
SELECT 3,   27282,       'M',          '09030301' FROM DUAL UNION ALL
SELECT 4,   12345,       'M',          '08202021' FROM DUAL;

CREATE TABLE tbl_client ( clnt_cd, first_name, last_name ) AS
SELECT 12345,      'Eren',         'Jaeger' FROM DUAL UNION ALL
SELECT 67891,      'Mikasa',       'Jaeger' FROM DUAL;

哪些输出:

CLNT_CD | FIRST_NAME | LAST_NAME | RESIDENCE_PHONE_NO | BUSINESS_PHONE_NO | CELLPHONE_PHONE_NO ------: | :--------- | :-------- | :----------------- | :---------------- | :----------------- 67891 |三笠 |积家 | | 043-2020 | 12345 |艾伦 |积家 | 09030102 | | 08202021

db小提琴here

【讨论】:

    【解决方案3】:

    这将为您的客户提供每种类型的电话号码,如果他们没有该类型,则为 null。请注意,我假设客户将只有一个任何给定类型电话的实例。

    SELECT tc.first_name
         , tc.last_name
         , phr.phone_no AS "Residence Telephone Number"
         , phb.phone_no AS "Office Telephone Number"
         , phm.phone_no AS "Cellphone Number"      
    FROM tbl_client tc 
    LEFT OUTER JOIN tbl_phone phr ON tc.clnt_cd = phr.clnt_cd
    LEFT OUTER JOIN tbl_phone phb ON tc.clnt_cd = phb.clnt_cd
    LEFT OUTER JOIN tbl_phone phm ON tc.clnt_cd = phm.clnt_cd
    WHERE phr.phone_type = 'R'
    AND   phb.phone_type = 'B'
    AND   phm.phone_type = 'M'
    /
    

    对于非常大量的数据,我很想使用子查询分解(WITH 子句)从 TBL_PHONE 中选择一次。

    【讨论】:

      【解决方案4】:

      您的查询中的问题是您错过了标量子查询中的 clnt_cd 谓词(也是列名,但我认为这是一个拼写错误或复制和粘贴问题)。

      select phone_no from tbl_phone where phone_type = 'M'
      

      返回 09030301 和 08202021,因此会出现“多行”错误。

      固定版本:

      select tc.first_name
           , tc.last_name
           , (select phone_no from tbl_phone tp where tp.clnt_cd = tc.clnt_cd and phone_type = 'R') as "Residence Telephone Number"
           , (select phone_no from tbl_phone tp where tp.clnt_cd = tc.clnt_cd and phone_type = 'B') as "Office Telephone Number"
           , (select phone_no from tbl_phone tp where tp.clnt_cd = tc.clnt_cd and phone_type = 'M') as "Cellphone Number"
      from   tbl_client tc;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-05-29
        • 1970-01-01
        • 2023-03-12
        • 1970-01-01
        • 2014-08-31
        • 1970-01-01
        • 1970-01-01
        • 2011-12-29
        相关资源
        最近更新 更多