【问题标题】:Selecting a column from a table and the Count() of a column in another table从表中选择一列和另一个表中一列的 Count()
【发布时间】:2022-01-05 09:57:03
【问题描述】:

考虑下表:

   TABLE PAPER // it contains IDs of scientific papers and IDs of the scientists who wrote them
╔═══════════╦═════════════╗
║ PaperID   ║ ScientistID ║
╠═══════════╬═════════════╣
║ 10        ║ 1           ║
╠═══════════╬═════════════╣
║ 11        ║ 1           ║
╠═══════════╬═════════════╣
║ 12        ║ 2           ║
╠═══════════╬═════════════╣
║ 13        ║ 3           ║
╚═══════════╩═════════════╝


   TABLE SCIENTISTS // it contains IDs of scientists and their names
╔═════════════╦════════════════╗
║ ScientistID ║ ScientistName  ║
╠═════════════╬════════════════╣
║ 1           ║ Tikola Nesla   ║
╠═════════════╬════════════════╣
║ 2           ║ Carie Murie    ║
╠═════════════╬════════════════╣
║ 3           ║ Nsaac Iewton   ║
╚═════════════╩════════════════╝

我正在寻找一个 SELECT 查询来打印科学家的姓名以及他们发表了多少次科学论文,所需的结果应该是这样的:

CountOfPapersPerScientist     ScientistName
-------------------------     -------------
                        2      Tikola Nesla 
                        1       Carie Murie
                        1      Nsaac Iewton

我能够使用这个打印每个科学家的论文数量:

SELECT COUNT(PaperID) FROM PAPER GROUP BY ScientistID;

但这不起作用:

SELECT COUNT(PaperID), ScientistName FROM PAPER, SCIENTISTS WHERE SCIENTISTS.ScientistID=PAPER.ScientistID GROUP BY PAPER.ScientistID;

ERROR at line 1:
ORA-00979: not a GROUP BY expression

什么是“GROUP BY 表达式”,为什么我的查询不是一个?我可以使用什么替代查询?

【问题讨论】:

标签: sql oracle sqlplus


【解决方案1】:

这就是你需要的,简单的分组和加入:

select s.ScientistName, count(p.paperId) CountOfPapersPerScientist
from paper p
join SCIENTISTS s on p.ScientistID = s.ScientistID
group by s.ScientistName

【讨论】:

  • 完美运行,非常感谢!你能解释一下为什么它以前不起作用吗?
  • @Chainsburg 您按 ScientistID while 分组,因此您只能选择 ScientistID 列和聚合,但您选择的是 ScientistName,因此您必须按 ScientistName 分组。也始终使用显式连接
  • @Chainsburg 如果您有两个同名的不同科学家,这可能不会给出预期的结果。
【解决方案2】:

什么是“GROUP BY 表达式”,为什么我的查询不是一个?

当您使用GROUP BY 子句时,SELECT 子句中的所有列都必须是:

  • 列在GROUP BY子句中;或
  • 封装在一个聚合函数中(如SUMCOUNTLISTAGG等)。

您有GROUP BY s.ScientistId 并在SELECT 子句中使用ScientistName,该子句既未列在GROUP BY 子句中,也未包含在聚合函数中。


你需要的是:

SELECT MAX(s.ScientistName) AS ScientistName,
       count(p.paperId) CountOfPapersPerScientist
FROM   paper p
       INNER JOIN scientists s
       On p.ScientistID = s.ScientistID
GROUP BY
       s.ScientistId;

SELECT s.ScientistName,
       count(p.paperId) CountOfPapersPerScientist
FROM   paper p
       INNER JOIN scientists s
       On p.ScientistID = s.ScientistID
GROUP BY
       s.ScientistId, s.ScientistName;

因为这两者都将按科学家标识符的主键分组。

如果您只按姓名分组,那么您会将碰巧同名的两位不同科学家的论文数量汇总在一起,这可能不是您想要的,您需要确保您是按某些东西分组每个科学家都是独一无二的(而且他们的名字可能不是唯一的)。


例如,如果您有数据:

CREATE TABLE Scientists (ScientistId PRIMARY KEY, ScientistName, DateOfBirth) AS
SELECT 1, 'Alice', DATE '2000-01-01' FROM DUAL UNION ALL
SELECT 2, 'Beryl', DATE '1990-01-01' FROM DUAL UNION ALL
SELECT 3, 'Carol', DATE '1980-01-01' FROM DUAL UNION ALL
SELECT 4, 'Alice', DATE '1970-01-01' FROM DUAL;

CREATE TABLE paper (PaperID, ScientistID) AS
SELECT 10, 1 FROM DUAL UNION ALL
SELECT 11, 1 FROM DUAL UNION ALL
SELECT 12, 2 FROM DUAL UNION ALL
SELECT 13, 3 FROM DUAL UNION ALL
SELECT 14, 4 FROM DUAL;

ALTER TABLE paper ADD CONSTRAINT paper__scientistid__fk FOREIGN KEY (ScientistId) REFERENCES Scientists (ScientistId);

然后上面的查询都输出:

SCIENTISTNAME COUNTOFPAPERSPERSCIENTIST
Alice 2
Beryl 1
Carol 1
Alice 1

每个独特的科学家都有一行(即使两个有相同的名字)。

但是,仅在 ScientistName 上天真地分组会输出:

SCIENTISTNAME COUNTOFPAPERSPERSCIENTIST
Alice 3
Beryl 1
Carol 1

这是错误的,因为有两个不同的科学家名为 Alice

db小提琴here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-30
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    • 2021-12-30
    • 1970-01-01
    • 2016-07-22
    • 2017-11-13
    相关资源
    最近更新 更多