如何在元组中选择最旧的值

时间:2018-10-28 23:41:26

标签: sql oracle group-by greatest-n-per-group

我在Oracle中使用sqlplus,我的问题是:

  • 查找具有最早出版年份的书的bookID,书名,作者和出版年份。
  • 然后找到作者拥有的不同书籍数量最多的作者的姓名 库(同一本书的多份副本只能算作一本书)。

这是我的数据库:

 drop table history;
 drop table currentloan;
 drop table member;
 drop table book;

 /*
    creates table with 6 variables
    assigns one primary key
    uses different data types for different cases
 */  

create table Book
(bookID             number(12) Primary Key,
 ISBN               number(13),
 title              varchar(50),
 author             varchar(20),
 publish_year       number(4),
 category           char(11));

 /*
    Inserts tuples with matching variables 
    uses different book categories for testing purposes  
 */ 

insert into Book values('7839494', '9780143122784', 'Guitar Zero', 'Gary Marcus', '2012', 'non-fiction');
insert into Book values('7839495', '9780143122784', 'Guitar Zero', 'Gary Marcus', '2012', 'non-fiction');
insert into Book values('7839496', '9780143122784', 'Guitar Zero', 'Gary Marcus', '2012', 'non-fiction');
insert into Book values('1405904', '9780071812436', 'Oracle Database 12c PL/SQL Programming', 'Michael McLaughlin', '2014', 'reference');
insert into Book values('9890304', '9781449343033', 'Oracle Essentials: Oracle Database 12c', 'Rick Greenwald', '2013', 'reference');
insert into Book values('1893409', '9781598635034', 'Music Theory for Computer Musicians', 'Michael Hewitt', '2008', 'non-fiction');
insert into Book values('3848598', '9781119247791', 'Java All-in-One For Dummies', 'Doug Lowe', '2017', 'non-fiction');
insert into Book values('3848599', '9781119247791', 'Java All-in-One For Dummies', 'Doug Lowe', '2017', 'non-fiction');
insert into Book values('3049891', '9780679805274', 'Oh, the Places Youll Go', 'Dr. Seuss', '1990', 'Childrens');
insert into Book values('3049892', '9780679805274', 'Oh, the Places Youll Go', 'Dr. Seuss', '1990', 'Childrens');
insert into Book values('3049893', '9780679805274', 'Oh, the Places Youll Go', 'Dr. Seuss', '1990', 'Childrens');
insert into Book values('9839209', '9780072465631', 'Database Management Systems', 'Raghu Ramakrishnan', '2008', 'reference');
insert into Book values('3234567', '9780316605106', 'Cirque du Freak: A Living Nightmare', 'Darren Shan', '2002', 'fiction');
insert into Book values('3234568', '9780316605106', 'Cirque du Freak: A Living Nightmare', 'Darren Shan', '2002', 'fiction');
insert into Book values('3234569', '9780316605106', 'Cirque du Freak: A Living Nightmare', 'Darren Shan', '2002', 'fiction');
insert into Book values('3234570', '9780316605106', 'Cirque du Freak: A Living Nightmare', 'Darren Shan', '2002', 'fiction');
insert into Book values('1239480', '9781421539645', 'DeathNote Black Edition Vol. 1', 'Tsugumi Ohba', '2010', 'fiction');
insert into Book values('5467878', '9780877798095', 'Merriam_Websters Collegiate Dictionary', 'Merriam_Webster', '2003', 'reference');
insert into Book values('5467879', '9780877798095', 'Merriam_Websters Collegiate Dictionary', 'Merriam_Webster', '2003', 'reference');
commit;

 /*
    Creates member table with 6 variables 
    assigns one primary key 
    uses not null to ensure efficiency
  */ 
create table Member
(memberID            number(15) Primary Key,
 lastname            char(15),
 firstname           char(15) not null,
 address             varchar(30),
 phone_number        number(10),
 limit               number(3));


 /*
    Uses insert to fill member table with values 
    ensures values differ for testing  
*/

insert into Member values ('00986845', 'Guevara', 'Merlyn', '9705 hardwood ln', '9806369324', '5');
insert into Member values ('00425663', 'Courtney', 'Kacey', '1520 glengarry dr', '9848339522', '5');
insert into Member values ('00327889',  'Wells', 'Trey', '650 zack rd', '9802428333', '5');
insert into Member values ('00546283', 'Lopez', 'Manny', '123 Road st', '7046368300', '10');
insert into Member values ('00728432', 'Mondragon', 'Alpha', '6100 Raven peak dr', '7043028422', '5'); 
insert into Member values ('00345674', 'Jones', 'David', '4321 Rowan Way', '9803334564', '7');
insert into Member values ('00456742', 'Smith', 'John', '3456 Circle Pl', '7043239098', '8');
commit;


  /*    Generates table to track books checked out 
        Initializes 4 different variables
 */
create table CurrentLoan
( memberID           number(15),
  bookID             number(12),
  loan_date          varchar(10),
  due_date           varchar(10),
  FOREIGN KEY(bookID) REFERENCES book(bookID),
  Foreign key(memberID) REFERENCES member(memberID));


 /*
    uses insert to add currently checked out books  
*/

insert into Currentloan values('00986845', '7839494', '09/28/2018', '12/28/2018');
insert into Currentloan values('00546283', '1405904', '08/12/2018', '11/12/2018');
insert into Currentloan values('00327889', '9839209', '09/05/2018', '12/05/2018');
insert into Currentloan values('00345674', '1239480', '08/04/2018', '10/12/2018');
insert into Currentloan values('00456742', '1893409', '07/04/2018', '10/04/2018');
insert into Currentloan values('00456742', '5467878', '07/05/2018', '10/05/2018');
insert into Currentloan values('00456742', '7839496', '07/05/2018', '10/05/2018');
insert into Currentloan values('00456742', '3848599', '07/05/2018', '10/05/2018');
insert into Currentloan values('00456742', '3049892', '07/05/2018', '10/05/2018');
insert into Currentloan values('00456742', '3234569', '07/05/2018', '10/05/2018');
insert into Currentloan Values('00986845', '3234568', '08/02/2018', '11/02/2018');
insert into Currentloan Values('00986845', '3049891', '08/02/2018', '11/02/2018');
insert into Currentloan Values('00986845', '3848598', '08/02/2018', '11/02/2018');
insert into Currentloan Values('00986845', '5467879', '08/02/2018', '11/02/2018');
insert into Currentloan Values('00986845', '3234570', '08/02/2018', '11/02/2018');
commit;


 /*     Generates table of books checked out in the past
     Initializes 4 variables 
    deterines primary and foreign keys
 */
create table History
(memberID            number(15),
 bookID              number(12),
 loan_date           varchar(10) Primary Key,
 return_date         varchar(10),
 Foreign Key(bookID) References book(bookID),
 Foreign Key(memberID) References member(memberID));
 /*
    uses insert to specify previously checked out books. 
 */
insert into History values ('00728432', '5467878', '02/08/2017', '04/05/2017');
insert into History values ('00986845', '3234567', '09/12/2017', '10/10/2017');
insert into History values ('00728432', '3848598', '07/14/2016', '09/04/2017');
insert into History values ('00986845', '1239480', '11/14/2016', '01/26/2017');
insert into History values ('00456742', '3234569', '07/05/2016', '09/02/2016');
commit;

我认为我的查询是正确的,但我不断收到错误消息,指出我无法在Have子句中执行此操作

Select bookID, title, author, publish_yea, Min(publish_year)
from Book 
group by bookID
having publish_year = Min(publish_year);

3 个答案:

答案 0 :(得分:2)

我希望您的查询中显示错误消息mySubset。您在group by子句中缺少3个列名,应该这样写,以避免出现该错误:

Select bookID, title, author, publish_year, Min(publish_year)
from Book 
group by bookID , TITLE, AUTHOR, PUBLISH_YEAR
having publish_year = Min(publish_year);

,该查询将无法实现您要查找的内容。您正在按唯一值(主键)分组,因此您可以获取该查询返回的表的每一行。

ORA-00979: not a GROUP BY expression
BOOKID  | TITLE                                  | AUTHOR             | PUBLISH_YEAR | MIN(PUBLISH_YEAR)
:------ | :------------------------------------- | :----------------- | :----------- | :----------------
1893409 | Music Theory for Computer Musicians    | Michael Hewitt     | 2008         | 2008             
3848598 | Java All-in-One For Dummies            | Doug Lowe          | 2017         | 2017             
3234567 | Cirque du Freak: A Living Nightmare    | Darren Shan        | 2002         | 2002             
7839495 | Guitar Zero                            | Gary Marcus        | 2012         | 2012             
3049891 | Oh, the Places Youll Go                | Dr. Seuss          | 1990         | 1990             
3049893 | Oh, the Places Youll Go                | Dr. Seuss          | 1990         | 1990             
7839496 | Guitar Zero                            | Gary Marcus        | 2012         | 2012             
3234568 | Cirque du Freak: A Living Nightmare    | Darren Shan        | 2002         | 2002             
5467878 | Merriam_Websters Collegiate Dictionary | Merriam_Webster    | 2003         | 2003             
3049892 | Oh, the Places Youll Go                | Dr. Seuss          | 1990         | 1990             
1239480 | DeathNote Black Edition Vol. 1         | Tsugumi Ohba       | 2010         | 2010             
9890304 | Oracle Essentials: Oracle Database 12c | Rick Greenwald     | 2013         | 2013             
3848599 | Java All-in-One For Dummies            | Doug Lowe          | 2017         | 2017             
7839494 | Guitar Zero                            | Gary Marcus        | 2012         | 2012             
3234570 | Cirque du Freak: A Living Nightmare    | Darren Shan        | 2002         | 2002             
5467879 | Merriam_Websters Collegiate Dictionary | Merriam_Webster    | 2003         | 2003             
1405904 | Oracle Database 12c PL/SQL Programming | Michael McLaughlin | 2014         | 2014             
9839209 | Database Management Systems            | Raghu Ramakrishnan | 2008         | 2008             
3234569 | Cirque du Freak: A Living Nightmare    | Darren Shan        | 2002         | 2002             

由Turbero给出,全球最早年份的子查询将起作用:

Select bookID, title, author, publish_year, Min(publish_year)
from Book 
group by bookID, title, author, publish_year
having publish_year = Min(publish_year)
BOOKID  | TITLE                   | AUTHOR    | PUBLISH_YEAR
:------ | :---------------------- | :-------- | :-----------
3049891 | Oh, the Places Youll Go | Dr. Seuss | 1990        
3049892 | Oh, the Places Youll Go | Dr. Seuss | 1990        
3049893 | Oh, the Places Youll Go | Dr. Seuss | 1990        

或,或者可以使用窗口函数select bookID, title, author, publish_year from Book WHERE publish_year = (SELECT min(publish_year) FROM Book) (或rank()

dense_rank()
BOOKID  | TITLE                   | AUTHOR    | PUBLISH_YEAR
:------ | :---------------------- | :-------- | :-----------
3049891 | Oh, the Places Youll Go | Dr. Seuss | 1990        
3049893 | Oh, the Places Youll Go | Dr. Seuss | 1990        
3049892 | Oh, the Places Youll Go | Dr. Seuss | 1990        

在此处在线查看上述所有查询 db <>小提琴here

答案 1 :(得分:1)

您选择的“ publish_yea”中有一个小错字。

我在https://sqliteonline.com/中预加载了您的数据库,然后以固定的错字运行查询:

select bookID, title, author, publish_year, Min(publish_year)
from Book 
group by bookID
having publish_year = Min(publish_year);

有效。

但是该查询为您提供每个组的最小发布年份,而不是全局最小值。该查询可以做到:

select bookID, title, author, publish_year
from Book
WHERE publish_year = (SELECT min(publish_year) FROM Book) 

答案 2 :(得分:0)

在Oracle 12C +中,您可以使用fetch first。假设只需要一行:

Select bookID, title, author, publish_yea, publish_year
from Book 
order by publish_year desc
fetch first 1 rows only;

在早期版本中,另一个答案中提供的rank()解决方案可能是最好的方法。