Mysql 在与其他表进行比较时,从第三个表中选择记录

Mysql 在与其他表进行比较时,从第三个表中选择记录,mysql,sql,Mysql,Sql,我得到了3个表:artists、transactions和works,其中包含以下字段: artists:ArtistsID,LastName,FirstName 事务:事务ID、工作ID、客户ID 工作-工作ID,艺术家SID 我想做的是: 选择画廊尚未出售其作品的每位艺术家的姓氏和名字 到目前为止,我所做的是: SELECT FirstName , LastName FROM listofartists , work , trans WHERE listofart

我得到了3个表:
artists
transactions
works
,其中包含以下字段:

  • artists
    ArtistsID
    LastName
    FirstName
  • 事务
    :事务ID、工作ID、客户ID
  • 工作
    -
    工作ID
    艺术家SID
我想做的是:
选择画廊尚未出售其作品的每位艺术家的姓氏和名字

到目前为止,我所做的是:

SELECT FirstName
    , LastName
FROM listofartists
    , work
    , trans
WHERE listofartists.ArtistID = work.ArtistID
    AND trans.WorkID NOT IN (
        SELECT workID
        FROM work
    )

使用
左连接
并检查是否可以建立与
为空的关系

SELECT listofartists.FirstName, listofartists.LastName
FROM listofartists
LEFT JOIN work ON listofartists.ArtistID = work.ArtistID
LEFT JOIN trans ON trans.WorkID = work.workID 
WHERE work.workID IS NULL

使用
左连接
并检查是否可以建立与
为空的关系

SELECT listofartists.FirstName, listofartists.LastName
FROM listofartists
LEFT JOIN work ON listofartists.ArtistID = work.ArtistID
LEFT JOIN trans ON trans.WorkID = work.workID 
WHERE work.workID IS NULL

这可以通过使用
LEFT JOIN
并检查
notnull
约束来实现

SQL查询将如下所示:

SELECT A.FirstName, A.LastName
FROM artists A
JOIN work W ON A.ArtistID = W.ArtistID
LEFT JOIN transactions T ON T.WorkID = W.workID 
WHERE T.TransactionID IS NULL
在上面的查询中,我们将
艺术家
表与
作品
表连接,以获取每个艺术家的所有作品,然后我们将
作品
表与
事务
表进行左连接,该表将提供所有作品,无论其在事务表中的条目如何


最后一个条件是确保
TransactionID
为NULL,这意味着工作不会出现在任何事务中。

这可以通过使用
左连接
并检查
非NULL
约束来完成

SQL查询将如下所示:

SELECT A.FirstName, A.LastName
FROM artists A
JOIN work W ON A.ArtistID = W.ArtistID
LEFT JOIN transactions T ON T.WorkID = W.workID 
WHERE T.TransactionID IS NULL
在上面的查询中,我们将
艺术家
表与
作品
表连接,以获取每个艺术家的所有作品,然后我们将
作品
表与
事务
表进行左连接,该表将提供所有作品,无论其在事务表中的条目如何


最后一个条件是确保
TransactionID
为NULL,这意味着工作不会出现在任何事务中。

您的原始查询几乎是正确的,如果您想保持
不在
构造中,您可以按如下方式更改查询:

您不需要from子句中的
trans
表,您需要稍微更改where子句,如下所示

这将为您提供那些存在于工作表中但其作品不存在于trans表中的艺术家:

SELECT FirstName, LastName
FROM listofartists
JOIN work ON listofartists.ArtistID = work.ArtistID 
WHERE work.WorkID NOT IN (SELECT workID FROM trans)

该查询将排除根本没有任何作品的艺术家,但如果艺术家同时拥有已售出和未售出的作品,则将包括在内-不清楚是否要排除既有已售出和未售出作品的艺术家。

您最初的查询几乎正确,如果您想使
不在
结构中,可以按如下方式更改查询:

您不需要from子句中的
trans
表,您需要稍微更改where子句,如下所示

这将为您提供那些存在于工作表中但其作品不存在于trans表中的艺术家:

SELECT FirstName, LastName
FROM listofartists
JOIN work ON listofartists.ArtistID = work.ArtistID 
WHERE work.WorkID NOT IN (SELECT workID FROM trans)

该查询将排除根本没有任何作品的艺术家,但如果艺术家既有已售出作品又有未售出作品,则将包括在内-不清楚是否要排除既有已售出作品又有未售出作品的艺术家。

是否有一种不必加入
部分的方法?我们还没有了解到这一点。@user6219654查询中的逗号是连接。在20世纪90年代,您学习编写查询的方式实际上已被弃用。@user6219654您可以进行隐式联接(如在原始查询中):
SELECT FirstName,LastName FROM listofartists,work WHERE listofartists.ArtistID=work.ArtistID和work.WorkID NOT in(SELECT WorkID FROM trans)
但是使用
join
关键字的显式连接是首选的,因为它们是在1992年引入的,最好尽早学习“正确”的方法:)@jpw我们可能会晚些时候学习它,但说明是根据我们现在知道的事情找到解决方案。然而,我似乎不明白,为什么把trans放在FROM上对我不起作用me@user6219654当您在from子句中放入
trans
,而where子句中没有指定如何将该表连接到其他表的任何匹配条件时,您可以有效地创建笛卡尔连接(trans中的所有行到其他集合中的所有行的映射)这不是你需要的。但是,您可以使用其他答案中指出的左连接来完成此操作-这些显式左连接也可以重写为隐式连接。是否有一种不使用
连接
部分的方法来完成此操作?我们还没有了解到这一点。@user6219654查询中的逗号是连接。在20世纪90年代,您学习编写查询的方式实际上已被弃用。@user6219654您可以进行隐式联接(如在原始查询中):
SELECT FirstName,LastName FROM listofartists,work WHERE listofartists.ArtistID=work.ArtistID和work.WorkID NOT in(SELECT WorkID FROM trans)
但是使用
join
关键字的显式连接是首选的,因为它们是在1992年引入的,最好尽早学习“正确”的方法:)@jpw我们可能会晚些时候学习它,但说明是根据我们现在知道的事情找到解决方案。然而,我似乎不明白,为什么把trans放在FROM上对我不起作用me@user6219654当您在from子句中放入
trans
,而where子句中没有指定如何将该表连接到其他表的任何匹配条件时,您可以有效地创建笛卡尔连接(trans中的所有行到其他集合中的所有行的映射)这不是你需要的。不过,您可以使用其他答案中指出的左连接来完成此操作-这些显式左连接也可以重写为隐式连接。