Sql 统计当前和历史中每个成员的帐簿
我怎样才能开始写这个查询?我正在考虑使用计数、内部联接和分组方式 CurrentLoan是当前图书的签出,History是以前签出的图书 目标:为每个成员(成员ID、姓氏和名字)列出成员当前签出的图书数量以及成员过去签出的图书数量。如果一个成员多次签出同一本书,则该书将被计算多次。如果成员没有图书签出,则应将其计为0 代码: 这是我到目前为止所得到的,询问:Sql 统计当前和历史中每个成员的帐簿,sql,oracle,Sql,Oracle,我怎样才能开始写这个查询?我正在考虑使用计数、内部联接和分组方式 CurrentLoan是当前图书的签出,History是以前签出的图书 目标:为每个成员(成员ID、姓氏和名字)列出成员当前签出的图书数量以及成员过去签出的图书数量。如果一个成员多次签出同一本书,则该书将被计算多次。如果成员没有图书签出,则应将其计为0 代码: 这是我到目前为止所得到的,询问: SELECT Member.memberID, lastname, firstname, COUNT (CurrentLoan.bookI
SELECT Member.memberID, lastname, firstname, COUNT (CurrentLoan.bookID) as numberofbooks
FROM Member
INNER JOIN CurrentLoan ON Member.memberID = CurrentLoan.memberID
INNER JOIN Book ON CurrentLoan.bookID = Book.bookID
GROUP BY Member.memberID, lastname, firstname
这就是我想要的输出:
memberID lastname firstname numberofbooks
1 Lee Nancy 0
2 Le Ray 0
3 Kan Charlie 0
4 Brown Joe 2
5 Smith John 1
6 Khang Nkaujyi 2
7 Jones David 2
8 Lee Tou 4
9 Jones John 4
要在count列中获得零,数据中需要NULL,因为count()对于NULL不会增加1,但对于任何非NULL值都会增加。要在结果中获得空值,请使用外部联接(这里它们是左外部联接) 注意:除非要使用该表中的某个列,否则不需要第二个左连接 看看这个 :
| MEMBERID | LASTNAME | FIRSTNAME | CURRENT_ |
|----------|----------|-----------|----------|
| 1 | Lee | Nancy | 0 |
| 2 | Le | Ray | 0 |
| 3 | Kan | Charlie | 0 |
| 4 | Brown | Joe | 2 |
| 5 | Smith | John | 1 |
| 6 | Khang | Nkaujyi | 1 |
| 7 | Jones | David | 1 |
| 8 | Lee | Tou | 2 |
| 9 | Jones | John | 2 |
有历史记录
SELECT Member.memberID, lastname, firstname, COUNT (Loans.bookID) as Count_All
FROM Member
LEFT OUTER JOIN (
select memberID, bookID from CurrentLoan
union all
select memberID, bookID from History
) loans ON Member.memberID = Loans.memberID
/* LEFT OUTER JOIN Book ON CurrentLoan.bookID = Book.bookID */
GROUP BY Member.memberID, lastname, firstname
ORDER BY Member.memberID, lastname, firstname
要在count列中获得零,数据中需要NULL,因为count()对于NULL不会增加1,但对于任何非NULL值都会增加。要在结果中获得空值,请使用外部联接(这里它们是左外部联接) 注意:除非要使用该表中的某个列,否则不需要第二个左连接 看看这个 :
| MEMBERID | LASTNAME | FIRSTNAME | CURRENT_ |
|----------|----------|-----------|----------|
| 1 | Lee | Nancy | 0 |
| 2 | Le | Ray | 0 |
| 3 | Kan | Charlie | 0 |
| 4 | Brown | Joe | 2 |
| 5 | Smith | John | 1 |
| 6 | Khang | Nkaujyi | 1 |
| 7 | Jones | David | 1 |
| 8 | Lee | Tou | 2 |
| 9 | Jones | John | 2 |
有历史记录
SELECT Member.memberID, lastname, firstname, COUNT (Loans.bookID) as Count_All
FROM Member
LEFT OUTER JOIN (
select memberID, bookID from CurrentLoan
union all
select memberID, bookID from History
) loans ON Member.memberID = Loans.memberID
/* LEFT OUTER JOIN Book ON CurrentLoan.bookID = Book.bookID */
GROUP BY Member.memberID, lastname, firstname
ORDER BY Member.memberID, lastname, firstname
有趣的比较:参见
现在用这种方式试试:
SELECT Member.memberID, lastname, firstname, NVL(Loans.Count_All,0) Count_All
FROM Member
LEFT OUTER JOIN (
select memberID, count(bookID) as Count_All
from (
select memberID, bookID from CurrentLoan
union all
select memberID, bookID from History
) l
GROUP BY memberID
) loans ON Member.memberID = Loans.memberID
ORDER BY Member.memberID, lastname, firstname
;
-------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost | Time |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 15 | 945 | 10 | 00:00:01 |
| 1 | SORT ORDER BY | | 15 | 945 | 10 | 00:00:01 |
| * 2 | HASH JOIN OUTER | | 15 | 945 | 9 | 00:00:01 |
| 3 | TABLE ACCESS FULL | MEMBER | 9 | 333 | 3 | 00:00:01 |
| 4 | VIEW | | 15 | 390 | 5 | 00:00:01 |
| 5 | HASH GROUP BY | | 15 | 390 | 5 | 00:00:01 |
| 6 | VIEW | | 15 | 390 | 4 | 00:00:01 |
| 7 | UNION-ALL | | | | | |
| 8 | INDEX FAST FULL SCAN | SYS_C007213 | 9 | 234 | 2 | 00:00:01 |
| 9 | INDEX FAST FULL SCAN | SYS_C007216 | 6 | 156 | 2 | 00:00:01 |
-------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
------------------------------------------
* 2 - access("MEMBER"."MEMBERID"="LOANS"."MEMBERID"(+))
所以,在这个测试中,第二种方法不是更好的…有趣的比较:参见
现在用这种方式试试:
SELECT Member.memberID, lastname, firstname, NVL(Loans.Count_All,0) Count_All
FROM Member
LEFT OUTER JOIN (
select memberID, count(bookID) as Count_All
from (
select memberID, bookID from CurrentLoan
union all
select memberID, bookID from History
) l
GROUP BY memberID
) loans ON Member.memberID = Loans.memberID
ORDER BY Member.memberID, lastname, firstname
;
-------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost | Time |
-------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 15 | 945 | 10 | 00:00:01 |
| 1 | SORT ORDER BY | | 15 | 945 | 10 | 00:00:01 |
| * 2 | HASH JOIN OUTER | | 15 | 945 | 9 | 00:00:01 |
| 3 | TABLE ACCESS FULL | MEMBER | 9 | 333 | 3 | 00:00:01 |
| 4 | VIEW | | 15 | 390 | 5 | 00:00:01 |
| 5 | HASH GROUP BY | | 15 | 390 | 5 | 00:00:01 |
| 6 | VIEW | | 15 | 390 | 4 | 00:00:01 |
| 7 | UNION-ALL | | | | | |
| 8 | INDEX FAST FULL SCAN | SYS_C007213 | 9 | 234 | 2 | 00:00:01 |
| 9 | INDEX FAST FULL SCAN | SYS_C007216 | 6 | 156 | 2 | 00:00:01 |
-------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
------------------------------------------
* 2 - access("MEMBER"."MEMBERID"="LOANS"."MEMBERID"(+))
所以,在这个测试中,第二种方法不是更好…但它只适用于当前,而历史(过去)?它应该能够获得一个会员当前和历史的图书总数。天哪,为什么不自己尝试一下,更好的学习方式,但过一会儿我会添加缺少的join和count。我已经做了将近4个小时的这个问题,但没有得到它。是的,它仍然有效,但没有必要;完全外部联接比“左外部联接”
更“昂贵”,而且根本不会改善结果。
。您可以尝试在联接之前进行分组(即,联接联合贷款表的子查询),“可能”更有效,但它仅适用于当前,而历史(过去)?它应该能够获得一个会员当前和历史的图书总数。天哪,为什么不自己尝试一下,更好的学习方式,但过一会儿我会添加缺少的join和count。我已经做了将近4个小时的这个问题,但没有得到它。是的,它仍然有效,但没有必要;完全外部联接比“左外部联接”更“昂贵”,而且根本不会改善结果。
。您可以尝试在联接之前进行分组(即联接联合贷款表的子查询),“可能”更有效