关系分工

时间:2016-05-19 14:00:46

标签: mysql sql sql-server sqlite relational-division

我应该为这个陈述写一个查询:

  

列出客户购买整张专辑(即专辑中的所有曲目)的客户名称和专辑标题

我知道我应该使用师。

这是我的答案,但是我得到了一些我无法解决的奇怪的语法错误。

SELECT 
     R1.FirstName
     ,R1.LastName
     ,R1.Title
FROM (Customer C, Invoice I, InvoiceLine IL, Track T, Album Al) AS R1
WHERE 
     C.CustomerId=I.CustomerId 
     AND I.InvoiceId=IL.InvoiceId
     AND T.TrackId=IL.TrackId 
     AND Al.AlbumId=T.AlbumId
     AND NOT EXISTS ( 
          SELECT 
               R2.Title
           FROM (Album Al, Track T) AS R2
           WHERE 
                T.AlbumId=Al.AlbumId
                AND R2.Title NOT IN (
                    SELECT R3.Title
                    FROM (Album Al, Track T) AS R3
                    WHERE 
                        COUNT(R1.TrackId)=COUNT(R3.TrackId)
                )
     );

错误:misuse of aggregate function COUNT()

您可以找到数据库here

的架构

4 个答案:

答案 0 :(得分:2)

您无法为(Album Al, Track T)之类的表格列别名,这是(Album Al CROSS JOIN Track T)的过时语法。您可以为表格添加别名,例如Album Al或子查询,例如(SELECT * FROM Album CROSS JOIN Track) AS R2

首先,你应该直接加入你的联盟。我不是假设你正在教那些旧的以逗号分隔的连接,而是从一些旧书或网站中获取它们?请使用正确的显式连接。

然后你不能使用WHERE COUNT(R1.TrackId) = COUNT(R3.TrackId)COUNT是一个聚合函数,聚合在WHERE之后完成。

关于查询:比较曲目计数是一个好主意。所以,让我们一步一步地做到这一点。

查询以获取每张专辑的曲目数:

select albumid, count(*)
from track
group by albumid;

查询以获取每位客户和相册的曲目数:

select i.customerid, t.albumid, count(distinct t.trackid)
from track t
join invoiceline il on il.trackid = t.trackid
join invoice i on i.invoiceid = il.invoiceid
group by i.customerid, t.albumid;

完整查询:

select c.firstname, c.lastname, a.title
from
(
  select i.customerid, t.albumid, count(distinct t.trackid) as cnt
  from track t
  join invoiceline il on il.trackid = t.trackid
  join invoice i on i.invoiceid = il.invoiceid
  group by i.customerid, t.albumid
) bought
join
(
  select albumid, count(*) as cnt
  from track
  group by albumid
) complete on complete.albumid = bought.albumid and complete.cnt = bought.cnt
join customer c on c.customerid = bought.customerid
join album a on a.albumid = bought.albumid;

答案 1 :(得分:1)

似乎你在错误的地方使用计数

使用聚合函数

 SELECT R3.Title
    FROM (Album Al, Track T) AS R3
    HAVING  COUNT(R1.TrackId)=COUNT(R3.TrackId))

但请确保别名,因为在某些数据库中,别名在子查询中不可用..

答案 2 :(得分:0)

您应该简化查询。看看这个:

SELECT FirstName
    , LastName
    , Title
FROM (
    SELECT C.FirstName
         , C.LastName
         , A.AlbumID
         , A.Title
         , COUNT(DISTINCT TrackID) as TracksInvoiced
    FROM Customer C
    INNER JOIN Invoice I
    ON I.CustomerId = C.CustomerId
    INNER JOIN InvoiceLine IL
    ON I.InvoiceId = IL.InvoiceId
    INNER JOIN Track T 
    ON T.TrackID = I
    INNER JOIN Album A 
    ON A.AlbumID = T.AlbumID
    GROUP BY C.FirstName, C.LastName, A.AlbumID, A.Title
) C
INNER JOIN (
    SELECT AlbumID
        , COUNT(TrackID) as TotalTracks
    FROM Track
    GROUP BY AlbumID
) A
ON C.AlbumID = A.AlbumID
AND TracksInvoiced = TotalTracks

我使用了两个子选项,第一个用于计算每个客户和专辑的发票轨道,并将其与每个专辑的另一个子选项以及其中的轨道数量相连接,只有两个计数相等。

答案 3 :(得分:0)

这个似乎有点复杂:

SELECT r.FirstName, r.LastName, r.Title FROM
(
    SELECT C.FirstName as FirstName,
           C.LastName as LastName,
           A.Title as Title,
           A.AlbumId as AlbumId,
           COUNT(*) as count
    FROM Customer C, Invoice I, InvoiceLine IL, Track T, Album A
    WHERE C.CustomerId=I.CustomerId
      AND I.InvoiceId = IL.InvoiceId
      AND T.TrackId   = IL.TrackId
      AND A.AlbumId   = T.AlbumId
    GROUP BY C.CustomerId, A.AlbumId
) AS r
WHERE r.count IS IN
(
    SELECT COUNT(*) FROM Track T
    WHERE T.AlbumId = r.AlbumId
)

在更简单的基础上测试了这个想法,并扩展到您的示例,因此我不保证您可以立即复制和粘贴它的工作......