从 table 中选择一列,在另一个 table 中选择一列的 Count()

Selecting a column from a table and the Count() of a column in another table

考虑下表:

   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 表达式”以及为什么我的查询不是一个?我可以使用什么替代查询?

这是您需要的,简单的分组依据和加入:

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

What is a "GROUP BY expression" and why my query isn't one?

当您使用 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<>fiddle here