oracle sql中的相关查询

时间:2014-03-21 23:35:59

标签: sql oracle correlated-subquery

我有三张桌子:

Rent
+++++++++++++++++++++++++++++++++++++++
| title | copy_num | member_id | date |
+++++++++++++++++++++++++++++++++++++++
| ...   |...       |...        |...   |
++++++++++++++++++++++++++++++++++++++

Book
+++++++++++++++++++++++++++++++++++++++++++++
|title   | publisher| writer | publish_date |
+++++++++++++++++++++++++++++++++++++++++++++
| ...    |...       |...     |...           |
+++++++++++++++++++++++++++++++++++++++++++++

Member
+++++++++++++++++++++
| id | name | phone |
+++++++++++++++++++++
| ...|...   |...    |
+++++++++++++++++++++

我想为每位会员找到他最畅销书籍的出版商。例如,如果一个成员租用Hachette发布的更多书籍,结果应该是一行表明这一事实。所有成员的结果表应该是:

+++++++++++++++++++++++++++++++++++++++++++++++++++
| member_name | member_phone | favorite_publisher |
+++++++++++++++++++++++++++++++++++++++++++++++++++
| memberX     | 562214894    | Hachette           |
| ...         | ...          | ...                |
+++++++++++++++++++++++++++++++++++++++++++++++++++

我能够为具有id:11111111的特定成员执行此操作,并且没有使用此查询的电话号码:

SELECT id,
  publisher
FROM Rent R,
  Book B
WHERE R.member_id='11111111'
AND B.title     =R.title
GROUP BY member_id,
  publisher
HAVING COUNT(*)=
  (SELECT MAX(counter)
  FROM
    (SELECT member_id,
      publisher,
      COUNT(*) AS counter
    FROM Rent R,
      Book B
    WHERE R.member_id='11111111'
    AND B.title     =R.title
    GROUP BY member_id,
      publisher
    )
  ) ;

我不想使用PL-SQL来迭代上述查询。我想只使用SQL,但我不知道如何创建一个相关的子查询,所以我可以为每个成员做。

编辑1:我不想使用分析函数来解决问题。我想使用连接和相关子查询来解决问题。

3 个答案:

答案 0 :(得分:0)

请试试这个。注意:我已经测试过,因为我没有样本数据。您可能需要稍微修改一下。

select member_name, member_phone, Title, Rent_Count
from
(
    select m.member_name, m.member_phone, r.Title
    ,(
        select count(title)
        from Book
        where title = r.title
    ) as Rent_Count
    from Member m
    inner join Rent r on (r.member_id = m.id)
) r
order by Rent_Count desc

答案 1 :(得分:0)

此查询将从rent表中查找特定成员的发布者计数,然后找到最大计数以获得所需结果。

试一试

 SELECT m.NAME       member_name,
       m.phone      member_phone,
       cq.publisher favorite_publisher
  FROM (SELECT COUNT(1) cc,
               MAX(COUNT(1)) over(PARTITION BY member_id) maxc,
               a.member_id,
               b.publisher
          FROM rent a
         INNER JOIN book b ON a.title = b.title
         GROUP BY a.member_id,
                  b.publisher) cq
 INNER JOIN MEMBER m ON m.id = cq.member_id
 WHERE maxc = cc;

答案 2 :(得分:0)

您可以使用keep / first命令在Oracle中轻松完成此操作。 (阅读所有相关内容here。)这会使用子查询来计算每个成员/发布者的计数,然后使用第二级来保留最高出版商:

select mp.name, mp.phone,
       max(mp.publisher) keep (dense_rank first order by cnt desc) as favorite_publisher
from (select m.name, m.phone, b.publisher, count(*) as cnt
      from member m join
           rent r
           on r.member_id = m.member_id join
           book b
           on r.title = b.title
      group by m.name, m.phone, b.publisher
     ) mp
group by mp.name, mp.phone;