SQL无法分组...选项?

时间:2015-05-03 07:54:16

标签: sql select oracle9i

我有下表: involved_in表示电影和在其中工作的人之间的关系:

     FID        AID   JOB
 ---------- ---------- -----------------------------------
   2387816     226673 actor
   2146284     230306 actor
   1814529     233362 actor
   2146710     275818 actor
   2033140     324419 actor
   2387816     452297 actor
   1749641     522815 actor
   2379685     972581 actor
   2384487    1001930 actor
   2065098    1021573 actor

is_a表示两部电影之间的关系,因为电影a是电影b的前传:

   MOVID1     MOVID2     REL_ID
  ---------- ---------- ----------
  2455766    1858631          2
  2465356     716238         12
  2465467    1005316          2
  2465585    2046499          1
  2465793    1992318          6
  2465793    2144984          5
  2467514    1984530         15

在其他表格中,我可以获取上面使用的ID的标题和名称。

我想找到那些在电影中合作超过x次的演员导演,他们在约翰尼德普与蒂姆伯顿合作的电影中没有相关的电影。

问题来自x次和我真正小的数据库帐户,它不会让我有足够大的临时表。 我可以:

create view friends as
(select actor, director, film, count(*) over (PARTITION BY actor, director) as together
from
(select a.aid as actor, b.aid as director, a.fid as film
from involved_in a, involved_in b
where a.fid=b.fid AND (a.job='actor' or a.job='actress') AND b.job='director'));

这将给我每个演员 - 导演一对,他们一起工作的每部电影以及他们一起工作的次数。

视图太大,所以我可以先删除所有那些一起工作不到x次的对。使用group by actor,导演让我在电影中出错(不是按表达式分组)。

有没有办法限制计数小于x的行?我也试过了

having count(...) > x 

如果我能算数(演员,导演)那将是完美的,但当然这不是语法,因为它会很方便。

让我的朋友查看后我使用了这个查询:

select f1.actor, f1.director
from friends f1, friends f2, is_a
where f1.actor = f2.director and f2.actor = f1.director and NOT (f1.film = movid1 and f2.film = movid2);

我没有使用JOIN ON等等,因为我的老师说他们多余了,虽然我觉得它看起来更好,所以也许我最终会使用它们。

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

您已经有嵌套的select语句,只需添加另一个:

create view friends as
(
SELECT actor, director, film, together
FROM (
      select actor, director, film, count(*) over (PARTITION BY actor, director) as together
      from
           (
           select a.aid as actor, b.aid as director, a.fid as film
           from involved_in a 
           INNER JOIN involved_in b ON(a.fid=b.fid)
           WHERE (a.job='actor' or a.job='actress') 
           AND b.job='director'
           ) InnerMostQuey
     ) MiddleQuery
WHERE together > x -- Replace x with whatever number that makes you happy :-)
);

答案 1 :(得分:1)

我建议使用以下查询,对您进行一些重大调整并删除冗余。

使用显式JOINs以提高可读性,使用IN子句在代码中节省一些空间。无论如何,Planner都会翻译这个条款。

CREATE VIEW friends AS
SELECT
    actor, director, film, num_together
FROM(
    SELECT
        a.aid AS actor,
        b.aid AS director,
        a.fid AS film,
        COUNT(*) OVER (PARTITION BY a.aid, b.aid) AS num_together
    FROM
        involved_in a
        INNER JOIN involved_in b ON
            a.fid = b.fid
    WHERE
        a.job IN ('actor', 'actress')
        AND b.job = 'director'
    ) foo
WHERE
    num_together < 'x' -- placeholder for your "limit the rows that appear with count less than x"

尽管如此,这种观点可能会产生误导,因为它列出了演员和导演合作的次数,但它出现在他们共同合作的每部电影的旁边。