从同一个表中提取名称

时间:2017-05-11 21:44:40

标签: sql oracle

当只有客户#映射到名称时,需要repaycustomer#列的名称。

Customer# | CustomerName| RepayCustomer#| Loan#
123       | John Doe    | 456           | 1    
456       | Jane Doe    | 456           | 2
123       | John Doe    | 123           | 3

预期结果

Customer# | CustomerName| RepayCustomer#| Loan# | RepayCustomer 
123       | John Doe    | 456           | 1     | Jane Doe
456       | Jane Doe    | 456           | 2     | Jane Doe
123       | John Doe    | 123           | 3     | John Doe    

3 个答案:

答案 0 :(得分:1)

假设每个CUSTOMER#唯一地与单个CUSTOMERNAME关联,则标量子查询应该是生成预期结果所需的全部。

以下是一个例子。

首先创建测试表:

CREATE TABLE CUSTOMER(
  CUSTOMER# NUMBER,
  CUSTOMERNAME VARCHAR2(64),
  REPAYCUSTOMER# NUMBER,
  LOAN# NUMBER
);

并加载测试数据:

INSERT INTO CUSTOMER VALUES (123, 'John Doe',456,1);
INSERT INTO CUSTOMER VALUES (456, 'Jane Doe',456,2);
INSERT INTO CUSTOMER VALUES (123, 'John Doe',123,3);

然后运行查询:

SELECT
  CUSTOMER.CUSTOMER#,
  CUSTOMER.CUSTOMERNAME,
  CUSTOMER.REPAYCUSTOMER#,
  CUSTOMER.LOAN#,
  (SELECT DISTINCT REPAYCUSTOMER.CUSTOMERNAME
   FROM CUSTOMER REPAYCUSTOMER
   WHERE REPAYCUSTOMER.CUSTOMER# = CUSTOMER.REPAYCUSTOMER# ) AS REPAYCUSTOMER
FROM CUSTOMER;

结果:

CUSTOMER#  CUSTOMERNAME  REPAYCUSTOMER#  LOAN#  REPAYCUSTOMER  
123        John Doe      456             1      Jane Doe       
456        Jane Doe      456             2      Jane Doe       
123        John Doe      123             3      John Doe 

但请注意,如果CUSTOMER#CUSTOMERNAME之间的唯一关联存在歧义(例如,如果第一个客户#123为John Doe而第二个123为Chewbacca })此查询将(并且应该)失败。

如果CUSTOMERNAMECUSTOMER#之间的依赖关系为consolidated  这里需要DISTINCT得到缓解。

如果可能,可能值得考虑所提供的表的替代设计 - 这可以帮助使这样的提取可靠,并且可以帮助维护数据的完整性(以及约束行之间的层次关系) 。

答案 1 :(得分:0)

@alexgibbs的答案可以通过使用row_number()限制结果来稍微改善,以处理"歧义"他提到有多个行具有相同的CUSTOMER#但具有不同的客户名称。在存在不同名称的情况下,将始终按字母顺序选择第一个名称。

SELECT
  CUSTOMER.CUSTOMER#,
  CUSTOMER.CUSTOMERNAME,
  CUSTOMER.REPAYCUSTOMER#,
  CUSTOMER.LOAN#,
  (SELECT RC2.REPAYCUSTOMER FROM
      (SELECT CUSTOMERNAME AS REPAYCUSTOMER,
              ROW_NUMBER() AS SEQUENCE_NUMBER
         FROM CUSTOMER RC
        WHERE RC.CUSTOMER# = CUSTOMER.REPAYCUSTOMER#
        ORDER BY RC.CUSTOMERNAME) RC2
    WHERE RC2.SEQUENCE_NUMBER = 1)
FROM CUSTOMER;

请点击此处了解为什么您不能简单地使用rownum:How to use Oracle ORDER BY and ROWNUM correctly?

答案 2 :(得分:0)

假设您的表名是Customer:

SELECT C1.Customer#, C1.CustomerName, C1.RepayCustomer#, C1.Loan#,
C2.CustomerName
FROM Customer C1, (SELECT Customer#, CustomerName
                   FROM CUSTOMER) C2
WHERE C1.RepayCustomer#=C2.Customer#;