在SQL*Plus中不能将最大值与计数一起使用

在SQL*Plus中不能将最大值与计数一起使用,sql,oracle,aggregate-functions,ora-00937,Sql,Oracle,Aggregate Functions,Ora 00937,这是我的sql语句,我得到了这个错误。但是,当我只使用Max to single而不显示其他结果时,它就可以工作了。有人能帮我吗 SELECT cat.CategoryName,sb.SubCategoryName,MAX((COUNT(bs.BookID))) FROM Category cat,SubCategory sb, Book_Subcategory bs WHERE cat.CategoryID = sb.CategoryID AND sb.SubCategoryID =

这是我的sql语句,我得到了这个错误。但是,当我只使用Max to single而不显示其他结果时,它就可以工作了。有人能帮我吗

SELECT cat.CategoryName,sb.SubCategoryName,MAX((COUNT(bs.BookID))) 
FROM
  Category cat,SubCategory sb, Book_Subcategory bs 
WHERE cat.CategoryID = sb.CategoryID AND sb.SubCategoryID = bs.SubCategoryID 
GROUP BY cat.CategoryName, sb.SubCategoryName, bs.BookID;
第1行出现错误:
ORA-00937:没有单一的组功能


有人能帮我吗?

我认为错误在GROUP BY子句中(bs.BookID不属于该子句):


顺便说一句,空格(和标点符号)是你的朋友。不要偷懒。

我认为错误在GROUP BY子句中(bs.BookID不属于该子句):


顺便说一句,空格(和标点符号)是你的朋友。不要偷懒。

SQL不允许直接聚合聚合

但是,如果在FROM子句的子查询中写入内部聚合(或使用WITH子句和公共表表达式CTE),则可以获得以下结果:

SELECT gc1.CategoryName, gc1.SubCategoryName, gc1.BookCount
  FROM (SELECT cat.CategoryName, sb.SubCategoryName,
               COUNT(bs.BookID) AS BookCount
          FROM Category AS cat
          JOIN SubCategory AS sb ON cat.CategoryID = sb.CategoryID
          JOIN Book_Subcategory AS bs ON sb.SubCategoryID = bs.SubCategoryID
         GROUP BY cat.CategoryName, sb.SubCategoryName
       ) AS gc1
 WHERE gc1.BookCount = (SELECT MAX(gc2.BookCount)
                          FROM (SELECT cat.CategoryName, sb.SubCategoryName,
                                       COUNT(bs.BookID) AS BookCount
                                  FROM Category AS cat
                                  JOIN SubCategory AS sb
                                       ON cat.CategoryID = sb.CategoryID
                                  JOIN Book_Subcategory AS bs
                                       ON sb.SubCategoryID = bs.SubCategoryID
                                 GROUP BY cat.CategoryName, sb.SubCategoryName
                                ) AS gc2
                        )
这很复杂,因为它不使用CTE,并且有一个公共的表表达式必须写出两次

使用CTE表单(可能有语法错误):

整洁多了

如果DBMS使创建CTE变得容易,则可以使用临时表模拟CTE。例如,IBM Informix Dynamic Server可以使用:

SELECT cat.CategoryName, sb.SubCategoryName,
       COUNT(bs.BookID) AS BookCount
  FROM Category AS cat
  JOIN SubCategory AS sb ON cat.CategoryID = sb.CategoryID
  JOIN Book_Subcategory AS bs ON sb.SubCategoryID = bs.SubCategoryID
 GROUP BY cat.CategoryName, sb.SubCategoryName
  INTO TEMP gc1;

SELECT gc1.CategoryName, gc1.SubCategoryName, gc1.BookCount
  FROM gc1
 WHERE gc1.BookCount = (SELECT MAX(gc1.BookCount) FROM gc1);

DROP TABLE gc1;  -- Optional: table will be deleted at end of session anyway

给定以下表格和数据,主查询(从这个答案复制和粘贴)给出了在MacOS X 10.6.4上运行IBM Informix Dynamic Server 11.50.FC6时我所期望的结果,即:

Non-Fiction    SQL Theory    4
Fiction        War           4
这并不能证明它在与Oracle竞争时“必须工作”——我没有Oracle,也无法演示任何一种方法。它确实表明,至少有一个SQL DBMS可以毫无问题地处理查询。(由于IDS不支持WITH子句和CTEs,因此我无法说明该公式是否有效。)

模式 资料
SQL不允许直接聚合聚合

但是,如果在FROM子句的子查询中写入内部聚合(或使用WITH子句和公共表表达式CTE),则可以获得以下结果:

SELECT gc1.CategoryName, gc1.SubCategoryName, gc1.BookCount
  FROM (SELECT cat.CategoryName, sb.SubCategoryName,
               COUNT(bs.BookID) AS BookCount
          FROM Category AS cat
          JOIN SubCategory AS sb ON cat.CategoryID = sb.CategoryID
          JOIN Book_Subcategory AS bs ON sb.SubCategoryID = bs.SubCategoryID
         GROUP BY cat.CategoryName, sb.SubCategoryName
       ) AS gc1
 WHERE gc1.BookCount = (SELECT MAX(gc2.BookCount)
                          FROM (SELECT cat.CategoryName, sb.SubCategoryName,
                                       COUNT(bs.BookID) AS BookCount
                                  FROM Category AS cat
                                  JOIN SubCategory AS sb
                                       ON cat.CategoryID = sb.CategoryID
                                  JOIN Book_Subcategory AS bs
                                       ON sb.SubCategoryID = bs.SubCategoryID
                                 GROUP BY cat.CategoryName, sb.SubCategoryName
                                ) AS gc2
                        )
这很复杂,因为它不使用CTE,并且有一个公共的表表达式必须写出两次

使用CTE表单(可能有语法错误):

整洁多了

如果DBMS使创建CTE变得容易,则可以使用临时表模拟CTE。例如,IBM Informix Dynamic Server可以使用:

SELECT cat.CategoryName, sb.SubCategoryName,
       COUNT(bs.BookID) AS BookCount
  FROM Category AS cat
  JOIN SubCategory AS sb ON cat.CategoryID = sb.CategoryID
  JOIN Book_Subcategory AS bs ON sb.SubCategoryID = bs.SubCategoryID
 GROUP BY cat.CategoryName, sb.SubCategoryName
  INTO TEMP gc1;

SELECT gc1.CategoryName, gc1.SubCategoryName, gc1.BookCount
  FROM gc1
 WHERE gc1.BookCount = (SELECT MAX(gc1.BookCount) FROM gc1);

DROP TABLE gc1;  -- Optional: table will be deleted at end of session anyway

给定以下表格和数据,主查询(从这个答案复制和粘贴)给出了在MacOS X 10.6.4上运行IBM Informix Dynamic Server 11.50.FC6时我所期望的结果,即:

Non-Fiction    SQL Theory    4
Fiction        War           4
这并不能证明它在与Oracle竞争时“必须工作”——我没有Oracle,也无法演示任何一种方法。它确实表明,至少有一个SQL DBMS可以毫无问题地处理查询。(由于IDS不支持WITH子句和CTEs,因此我无法说明该公式是否有效。)

模式 资料
任何实现这种sql语句的简单方法,而不是使用这种复杂的方法。另一件事是在你给我的第一个代码中有一些问题。我试着检查一下。但给了我一个错误的说法,因为GC1没有正确结束。我在Oracle.FWIW中使用SQLPLUS:在写这个答案之后,我了解到Oracle不遵循SQL标准,在创建表别名时不允许AS。因此,您必须在Oracle中从Category Cat编写
(但大多数其他DBMS都允许这样做),而不是从Category AS Cat
编写
。任何实现这种sql语句的简单方法,而不是使用如此复杂的语句。另一件事是在你给我的第一个代码中有一些问题。我试着检查一下。但给了我一个错误的说法,因为GC1没有正确结束。我在Oracle.FWIW中使用SQLPLUS:在写这个答案之后,我了解到Oracle不遵循SQL标准,在创建表别名时不允许AS。因此,您必须在Oracle中从Category Cat
编写
,而不是从Category Cat
(但大多数其他DBMS允许这样做)。
INSERT INTO Category VALUES(1, 'Fiction');
INSERT INTO Category VALUES(2, 'Non-Fiction');

INSERT INTO SubCategory VALUES(2, 1, 'SQL Theory');
INSERT INTO SubCategory VALUES(2, 2, 'Mathematics');
INSERT INTO SubCategory VALUES(1, 3, 'Romance');
INSERT INTO SubCategory VALUES(1, 4, 'War');

INSERT INTO Book_SubCategory VALUES(1, 10);
INSERT INTO Book_SubCategory VALUES(2, 11);
INSERT INTO Book_SubCategory VALUES(3, 12);
INSERT INTO Book_SubCategory VALUES(3, 13);
INSERT INTO Book_SubCategory VALUES(4, 14);
INSERT INTO Book_SubCategory VALUES(1, 15);
INSERT INTO Book_SubCategory VALUES(1, 16);
INSERT INTO Book_SubCategory VALUES(2, 17);
INSERT INTO Book_SubCategory VALUES(1, 18);
INSERT INTO Book_SubCategory VALUES(3, 19);
INSERT INTO Book_SubCategory VALUES(4, 20);
INSERT INTO Book_SubCategory VALUES(4, 21);
INSERT INTO Book_SubCategory VALUES(4, 22);