无法弄清楚查询和子查询

时间:2013-09-09 14:20:13

标签: sql

我无法解决这个问题。 我正在为大学做一些修改练习,并希望在2天之前通过我的考试。

我尝试了一些事情(最后我会发布)。请善待,这是我的第一个数据库主题,所以我的尝试对你来说似乎很愚蠢。

问题如下: 目前哪位艺术家拥有最多的节目? 展示第一&艺术家的姓氏及其地址。 ORDER BY子句不能使用。 写一个SQL语句。 使用子查询。

数据库中的相关表格:

Shows (ShowName, ArtistId, ShowStartDate, ShowEndDate)
Artists (ArtistId, FirstName, FamilyName, Address, PhoneNum)

我们假设ArtistId,ShowStartDate,FirstName,FamilyName和Address不能为空。

现在,我认为我必须计算每个艺术家目前的节目数量。然后,获得拥有/拥有最多的艺术家的ArtistId。使用ArtistId检索艺术家详细信息(名称和地址)。

我得到了这个(这是非常错误的):

SELECT FirstName, FamilyName, Address
FROM Artists
WHERE ArtistId = (SELECT ArtistId
                  FROM Shows
                  WHERE ArtistId = (SELECT MAX(Counted) 
                                    FROM (SELECT ArtistId, COUNT(ArtistId) AS Counted
                                    FROM Shows
                                    WHERE ShowEndDate IS null
                                    GROUP BY ArtistId)
                  GROUP BY ArtistId));

嗯,我知道

SELECT ArtistId, COUNT(ArtistId)
FROM Shows
WHERE ShowEndDate IS null
GROUP BY ArtistId

给我一​​个表格,列出每个ArtistId被列出的次数。 这很好。 但是从这个结果表中,我需要获得具有最高计数的那个的ArtistId /。

这就是我失去的地方。

任何人都可以解释一下吗?

(至于我使用的DBMS:我们必须使用由大学创建和提供的。这是非常基本的SQL。比Access 2010更简单)。

谢谢

(如果你提供答案[谢谢谢谢你]你能否简要解释其背后的原因?)

2 个答案:

答案 0 :(得分:2)

您需要找到艺术家最多的节目数,然后通过重新运行计数查询找出哪些艺术家具有该数量,但应用与刚刚找到的最大值匹配的having子句。

select FirstName, FamilyName, Address
from Artists
where ArtistId in -- use an in() to select the artists
  (select ArtistId from -- just select the artist id from the results
    (select ArtistId, count(*) c -- re-run the count query, but see having clause
     from Shows
     where current_date between ShowStartDate and ShowEndDate
     group by ArtistId
     having count(*) = -- use a having clause to only select those with the max count
      (select max(c) from -- this is simply the maximum count
        (select ArtistId, count(*) c -- find all counts by artist
         from Shows
         where current_date between ShowStartDate and ShowEndDate
         group by ArtistId
        ) counts
      )
    )
  )

一些语法注释:

  • count(*) c表示列( count(*))被赋予别名 c,因此可以参考通过外部查询。您不能将其称为count(*),因为这会被解释为聚合尝试。
  • max(c)获取名为(或别名)c的列的最大值(AFAIK,您可以代码max(count(*)) - 也许您可以尝试一下 - 我只是输入了没有控制台来测试它)
  • counts别名,从结果集中选择时是语法要求

您尚未指定您正在使用的数据库,因此您可能必须将current_date替换为您的数据库等效数据库。

某些dbs允许您在查询中重用查询(使用with子句),这样可以避免重新运行count子查询。

此查询仅使用 子选择,但您也可以使用连接。

答案 1 :(得分:0)

试试这个:

SELECT FirstName, FamilyName, Address
FROM Artists
WHERE ArtistId IN (
    SELECT ArtistId
    FROM (
        SELECT ArtistId, COUNT(ArtistId) AS Counted
        FROM Shows
        WHERE ShowEndDate IS null
        GROUP BY ArtistId) S1
    WHERE Counted = (
        SELECT MAX(Counted) 
        FROM (
            SELECT ArtistId, COUNT(ArtistId) AS Counted
            FROM Shows
            WHERE ShowEndDate IS null
            GROUP BY ArtistId) S2
        GROUP BY ArtistId)
    );

这很简单,应该适合你的情况。