如何执行这些查询?

时间:2014-09-17 17:31:00

标签: sql oracle

我有这三个表:

create table albums(sernum number primary key, 
        Albname varchar2(30) not null,
        Artist varchar2(20) not null,
        Pdate number(4),
        Recompany varchar2(10),
        Media char(2) not null);

create table tracks(sernum number not null,
        song varchar2(50) not null,
        primary key(sernum, song),
        foreign key(sernum) references albums(sernum));

create table performers(sernum number not null,
        Artist varchar2(30) not null,
        Instrument varchar2(50) not null,
        primary key(sernum, Artist, Instrument),
        foreign key (sernum) references albums(sernum));

我想在sql oracle中执行两个查询:

  • 列出使用所有乐器的艺术家的名字。
  • 列出包含最多数量或歌曲的专辑名称。

这是我的尝试:

select distinct(a.Artist) from albums a where a.Artist like (select p.Artist, distinct(p.Instrument) from performers p) group by a.Artist, p.Instrument;

select a.Albname from albums a, inner join tracks t on where a.sernum in(select max(t.sernum) group by t.sernum);

2 个答案:

答案 0 :(得分:3)

查询1 - 获取已播放所有乐器的艺术家:

SELECT
  p.Artist
FROM
  (
    SELECT Artist, count(distinct Instrument) as InstrumentCount
    FROM performers
    GROUP BY artist
  ) p
  JOIN
    (
      SELECT COUNT(DISTINCT Instrument) as InstrumentCount
      FROM performers
    ) i
    ON p.InstrumentCount = i.InstrumentCount

解释:第一个子查询获取每位艺术家演奏的乐器数量。第二个子查询获得了独特乐器的数量。根据这个乐器数量,两者结合在一起,只给那些乐器数量达到最大值的艺术家。

-

查询2 - 获取包含最多歌曲数量的相册:

WITH
AlbumTrackCount
(
  SELECT
    sernum,
    COUNT(1) as TrackCount
  FROM tracks
  GROUP BY sernum
)
SELECT
  a.Albname
FROM albums a
  JOIN AlbumTrackCount atc
    ON a.sernum = atc.sernum
    AND atc.TrackCount =
      (
        SELECT MAX(TrackCount)
        FROM AlbumTrackCount
      )

解释:WITH up top建立了一个我们将重用的子查询;它让我们获得每张专辑中的曲目数。在下面,我们使用此专辑曲目计数加入专辑,并添加一个过滤器,只有那些曲目数等于任何专辑的最大曲目数的专辑。请注意,这与顶级查询不同,后者只获得了所有乐器;在这里,重要的是首先计算每张专辑中的曲目,然后获得这些曲目的最大值。

答案 1 :(得分:1)

以下是您的查询的一些问题:

SELECT DISTINCT (a.artist)
FROM   albums a
WHERE  a.artist LIKE (SELECT p.artist, 
                             distinct(p.Instrument) 
                      from   performers p) 
group by a.Artist, p.Instrument;
  1. LIKE表示您将使用通配符。与where子句中的子查询进行比较时,通常使用in作为运算符。
  2. DISTINCT不是函数。它始终适用于SELECT语句中的所有列。
  3. DISTINCTGROUP BY用于非常相似的目的。你很少在同一个声明中使用它们。
  4. 您无法在外部查询中引用相关子查询中的列(即where子句中的查询)。

  5. SELECT a.albname
    FROM              albums a, 
           inner join tracks t 
           on 
    where a.sernum in(select max(t.sernum) group by t.sernum);
    
    1. 您同时使用逗号和inner join连接两个表。逗号表示pre-SQL:1999语法,而INNER JOIN是SQL:1999。虽然从技术上讲,您可以在单个FROM子句中使用它们,但不能在一对表之间使用它们。此外,你不应该同时使用两者。 Sticj to SQL:1999。
    2. 您的ON子句为空。你应该在这里加入你的两张桌子。如果你真的想要没有连接条件,可以将连接更改为CROSS JOIN(重新迭代:你几乎肯定不会想要这个)。
    3. 您的SELECT语句没有FROM子句。这是不允许的。