如何将带有内连接语句的 Sql 查询转换为带有 Where 语句的 sql 查询(语句中没有内连接)

Posted

技术标签:

【中文标题】如何将带有内连接语句的 Sql 查询转换为带有 Where 语句的 sql 查询(语句中没有内连接)【英文标题】:How to convert Sql query with inner join statement to sql query with Where statement(no inner join in statement) 【发布时间】:2009-12-05 15:52:53 【问题描述】:

我已经使用 Qbe 在访问中生成了以下 sql 查询代码并将其转换为 sql。但是,我想要证明我在没有帮助的情况下做了,所以我打算取出所有内部连接语句并用 WHERE 语句替换它们。我该如何解决。请解释并提供答案。谢谢。

SQL 查询:

选择 Entertainer.EntertainerID、Entertainer.FirstName、Entertainer.LastName、 Booking.CustomerID、Booking.EventDate、BookingDetail.Category、BookingDetail.Duration、 Speciality.SpecialityDescription, EntertainerSpeciality.EntertainerSpecialityCost FROM (艺人 INNER JOIN (预订 INNER JOIN BookingDetail ON Booking.BookingID=BookingDetail.BookingID) 开启 Entertainer.EntertainerID=BookingDetail.EntertainerID) INNER JOIN (Speciality INNER JOIN EntertainerSpeciality ON Speciality.SpecialityID=EntertainerSpeciality.SpecialityID) ON Entertainer.EntertainerID=EntertainerSpeciality.EntertainerID WHERE (((Entertainer.EntertainerID)=[Enter EntertainerID]));

【问题讨论】:

为什么== INNER JOIN 绝对是首选的方法! 您为什么要这样做?这并不能证明什么。 糟糕的想法。离开内部连接。 如果你不能加入他们,打败他们? 【参考方案1】:

这是迄今为止我见过的最奇怪的 JOIN 语句。这是您的查询转换为 ANSI-89 语法:

SELECT e.entertainerid, 
       e.firstname, 
       e.lastname, 
       b.customerid, 
       b.eventdate, 
       bd.category, 
       bd.duration, 
       s.specialitydescription, 
       es.entertainerspecialitycost
  FROM Entertainer e,
       BookingDetail bd,
       Booking b,
       EntertainerSpeciality es,
       Speciality s
 WHERE e.entertainerid = bd.entertainerid
   AND b.bookingid = bd.bookingid
   AND e.entertainerid = es.entertainerid
   AND s.specialityid = es.specialityid
   AND e.entertainerid = [Enter EntertainerID]

在这里,您的原始查询已清理语法 - 它应该有助于更轻松地查看公共信息:

SELECT e.entertainerid, 
       e.firstname, 
       e.lastname, 
       b.customerid, 
       b.eventdate, 
       bd.category, 
       bd.duration, 
       s.specialitydescription, 
       es.entertainerspecialitycost
  FROM ENTERTAINER e
  JOIN BOOKINGDETAIL bd ON bd.entertainerid = e.entertainerid
  JOIN BOOKING b ON b.bookingid = bd.bookingid
  JOIN ENTERTAINERSPECIALITY es ON es.entertainerid = e.entertainerid
  JOIN SPECIALITY s ON s.specialityid = es.specialityid
 WHERE e.entertainerid = ?

不同之处在于 ANSI-89 语法在 WHERE 子句中包括连接条件以及实际的过滤条件。强调一下,ANSI-92:

  FROM ENTERTAINER e
  JOIN BOOKINGDETAIL bd ON bd.entertainerid = e.entertainerid

...与 ANSI-89:

  FROM ENTERTAINER e,
       BOOKINGDETAIL bd
       ,... -- omitted for purpose of example
 WHERE e.entertainerid = bd.entertainerid

ANSI-92 语法是首选:

ANSI-89 并未在各种数据库中始终如一地实现 LEFT JOIN 语法,因此语句是可移植的 ANSI-92 提供了更强大的 JOIN(即:x ON x.id = y.id AND x.col IS NOT NULL) ANSI-92 更易于阅读,将连接条件与实际过滤条件分开

【讨论】:

这种使用 where 的连接已被贬值,但不应再使用。 @Johan:两者都会产生相同的查询计划,我的回答已经解释了选择一个而不是另一个的原因。那你的意思是什么? @OMG_Ponies,只是在完全阅读答案之前陈述显而易见的事情,我猜我被什么东西分心了。【参考方案2】:

想要做这件事很奇怪(正如评论者所说,INNER JOIN 通常更好,并且应用机械转换证明不了任何事情),但并不困难。每个 INNER JOIN 都可以机械地转换为 WHERE,如下所示:

而不是每个2路内连接A INNER JOIN B ON (cond1) WHERE (cond2)

改写为A, B WHERE (cond1) AND (cond2)

无论表 AB 以及条件 cond1cond2 可能是什么。

【讨论】:

但它看起来像一个嵌套语句。为了开始一个新的选择语句并继续嵌套,我需要什么?从我的推论中,我看到预订表与 bookingdetails 表连接,结果被连接到娱乐表中。如果我使用 Where 语句,我该如何表达? 内连接的嵌套无关紧要:SELECT ... FROM A INNER JOIN (B INNER JOIN C ON c1) ON c2 WHERE c3 因此变为SELECT ... FROM A, B, C WHERE c1 AND c2 AND c3

以上是关于如何将带有内连接语句的 Sql 查询转换为带有 Where 语句的 sql 查询(语句中没有内连接)的主要内容,如果未能解决你的问题,请参考以下文章

PYSPARK:如何将带有多个 case 语句的 SQL 查询转换为 Pyspark/Pyspark-SQL?

将带有连接的 SQL 查询转换为 lambda 表达式

C# 将带有 Case 语句的 SQL 查询转换为 LINQ

如何将带有子查询的 MySQL select 语句转换为同一张表的更新语句?

如何将带有子选择的 SQL 查询转换为 MDX 查询?

如何对带有联接的 SQL 查询的结果应用分页?