【问题标题】:SELECT values where their foreign keys are duplicate选择外键重复的值
【发布时间】:2020-06-06 07:10:27
【问题描述】:

假设我们有clientsproviders。一个客户可以有多个供应商(如互联网、电话、电视等),我想找到有多个供应商的客户的名字。

create table clients
(
    client_id char(8) not null,
    client_name varchar(80) not null,
    contract char(1) not null,
    primary key (client_id)
)

create table client_provider
(
    provider_id char(11) not null,
    client_id char(8) not null,
    primary key (provider_id, client_id),
    foreign key (provder_id) references providers ON DELETE CASCADE,
    foreign key (client_id) references clients ON DELETE CASCADE
);

因此,即使对providers一无所知,我们也可以通过以下关系代数了解拥有多个提供者的客户(刚开始学习,如有错误请指正):

π 客户端名称 (

[ σ client_provider2.provider_id ≠ client_provider.provider_id ∧ client_provider2.client_id = client_provider.client_id (ρ client_provider2 (client_provider) ⨯ client_provider))

⨝ 客户]

到目前为止我所尝试的(在第 1 行返回“不是 GROUP BY 表达式”):

SQL> select c.client_name 
  2  from clients c
  3  inner join client_provider cp on c.client_id = cp.client_id
  4  group by cp.client_id
  5  having count(*) > 1;

【问题讨论】:

  • 只需将您的group by 更改为c.client_name

标签: sql oracle sqlplus


【解决方案1】:

使用GROUP BY 时,所有使用的列都应位于GROUP BY 或聚合函数中。要解决此问题,请执行以下操作:

  1. SELECT 子句中添加cp.client_id
  2. GROUP BY 子句中添加c.client_name
SELECT
    cp.client_id,
    c.client_name
FROM clients c
INNER JOIN client_provider cp
    ON c.client_id = cp.client_id
GROUP BY
    cp.client_id,
    c.client_name
HAVING
    COUNT(1) > 1

【讨论】:

  • 对于count(1) > 1,你的意思是count(*) > 1吗?
  • 我也需要这个来只返回客户的名字。不是客户的身份证。我该怎么做?
  • COUNT(*) > 1COUNT(1) > 1 在这种情况下会产生相同的结果。如果您不想要client_id,则将其从SELECTGROUP BY 子句中删除
【解决方案2】:

所有非聚合列必须在group by 子句中,现在你知道了。

正如您评论说您只想显示 client_name 而不是 client_id(虽然它必须在 group by 子句中),请使用当前查询作为 source 以获得最终结果:

select client_name
from (-- current query begins here
      select cp.client_id,
             c.client_name
      from clients c join client_provider cp on c.client_id = cp.client_id
      group by cp.client_id, 
               c.client_name
      having count(*) > 1
      -- current query ends here
     );

或者,您可以使用(稍作修改的)当前查询作为子查询来做到这一点:

select cl.client_name
from client cl
where cl.client_id in (select cp.client_id
                       from client_provider cp
                       group by cp.client_id
                       having count(*) > 1
                      );

【讨论】:

    猜你喜欢
    • 2012-03-04
    • 1970-01-01
    • 1970-01-01
    • 2019-04-02
    • 2017-02-14
    • 1970-01-01
    • 1970-01-01
    • 2021-12-19
    • 1970-01-01
    相关资源
    最近更新 更多