【问题标题】:How to remove duplicate columns from join in SQL如何从 SQL 中的联接中删除重复的列
【发布时间】:2016-04-23 08:07:35
【问题描述】:

我有以下代码

SELECT * 
FROM customer
INNER JOIN
    (SELECT   
         customerid, newspapername, enddate, n.publishedby 
     FROM
         newspapersubscription ns, newspaper n 
     WHERE 
         publishedby IN (SELECT publishedby 
                         FROM newspaper 
                         WHERE ns.newspapername = n.NewspaperName)
UNION

SELECT
    customerid, Magazinename, enddate, m.publishedby 
FROM
    magazinesubscription ms, magazine m 
WHERE
    publishedby IN (SELECT publishedby 
                    FROM magazine 
                    WHERE ms.Magazinename = m.MagazineName)) ON customer.customerid = customerid
ORDER BY 
    customer.customerid;

客户表有以下内容:

 customerid | customername | customersaddress

此查询返回以下结果:

customerid | customername | customersaddress | customerid | newspapername | enddate| publishedby

我真正想要的是

customerid | customername | customersaddress | newspapername | magazinename | enddate| publishedby

此处,如果存在杂志名称,则报纸名称字段应为空白,反之亦然。此外,不应存在来自联合操作的 customerid 重复字段,而在我的结果中,报纸名称和杂志名称的值都放在报纸名称标题下。

我该怎么做?

【问题讨论】:

  • 您希望 customerid 在结果中出现两次?还是那是一个错字?
  • Bad habits to kick : using old-style JOINs - 旧式 逗号分隔的表格列表 样式已替换为 ANSI 中的 proper ANSI JOIN 语法-92 SQL 标准(20 多年前),不鼓励使用它

标签: sql oracle


【解决方案1】:

要获得所需的投影,请构建正确形状的子查询并将它们联合起来以获得结果集。 UNION ALL 比 UNION 更好,因为它避免了排序:你知道你会得到一个不同的集合,因为你要加入两个不同的表。

select * from (
    select customer.* 
           , n.newspapername
           , null as magazinename
           , ns.enddate
          , n.publishedby 
    from customer
        join newspapersubscription ns 
            on ns.customerid = customer.customerid
        join newspaper n
            on  n.newspapername = ns.newspapername 
    union all
    select customer.* 
           , null as newspapername
           , m.magazinename
           , ms.enddate
           , m.publishedby 
    from customer
        join magazinesubscription  ms 
            on ms.customerid = customer.customerid
        join magazine m
            on  m.magazinename = ms.magazinename 
            )
order by customerid, newspapername nulls last, magazinename ;

这是我的玩具数据集的输出(缺少publishedby 列:

CUSTOMERID CUSTOMERNAME         NEWSPAPERNAME          MAGAZINENAME           ENDDATE
---------- -------------------- ---------------------- ---------------------- ---------
        10 DAISY-HEAD MAISIE    THE DAILY BUGLE                               30-SEP-17
        30 FOX-IN-SOCKS         THE DAILY BUGLE                               30-SEP-17
        30 FOX-IN-SOCKS         THE WHOVILLE TIMES                            30-SEP-16
        30 FOX-IN-SOCKS                                GREEN NEWS             31-DEC-17
        30 FOX-IN-SOCKS                                TWEETLE BEETLE MONTHLY 31-DEC-16
        40 THE LORAX                                   GREEN NEWS             31-DEC-18

6 rows selected.

SQL>

【讨论】:

  • 你为什么在联合周围使用子查询 - 这似乎没有添加任何东西?
  • @AlexPoole - 当客户订阅不止一份报纸和杂志时,左连接的问题是避免使用笛卡尔积。外部查询是在 ORDER BY 子句中避免 ORA-00904 的一种方式另一种方式是 order by 1, 3, 4
  • 好的,你得到 ORA-00904 因为如果customer.*;我不知道。另一个不使用* 的原因。
【解决方案2】:

由于您使用“*”查询表,因此您将始终获得两个表中的所有列。为了省略此列,您必须手动命名您想要查询的所有列。为了满足您的其他需求,您只需在联合查询中的每个子句中插入一个虚拟列。下面是一个示例,应该可以满足您的需求 -

SELECT customer.customerid, customer.customername, customer.customeraddress, newspapername, magazinename, enddate, publishedby 
FROM customer
INNER JOIN
(select  customerid, newspapername, null Magazinename, enddate, n.publishedby 
 from newspapersubscription ns, newspaper n 
 where publishedby in(select publishedby 
                    from newspaper 
                    where ns.newspapername = n.NewspaperName)
UNION
select  customerid, null newspapername, Magazinename, enddate, m.publishedby 
from magazinesubscription ms, magazine m 
 where publishedby in(select publishedby 
                    from magazine 
                     where ms.Magazinename = m.MagazineName))
on customer.customerid = customerid
ORDER BY customer.customerid;

【讨论】:

    猜你喜欢
    • 2020-01-23
    • 2013-11-18
    • 1970-01-01
    • 2023-03-03
    • 2012-09-06
    • 2018-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多