Mysql 关于左外联接的问题

Mysql 关于左外联接的问题,mysql,database,join,Mysql,Database,Join,我非常确定我需要在我的表上进行左外部联接,但我不确定这是100%正确的还是在mySQL中编写它们的语法 我写下了这个问题: select m.mechanic_id, m.mechanic_name, m.city, m.state, count(mr.mechanic_id) as num_ratings, round(avg(mr.quality_id),2) quality_rating round(avg(mr.friendly_id),2)

我非常确定我需要在我的表上进行左外部联接,但我不确定这是100%正确的还是在mySQL中编写它们的语法

我写下了这个问题:

select m.mechanic_id, 
   m.mechanic_name, 
   m.city, 
   m.state, 
   count(mr.mechanic_id) as num_ratings, 
   round(avg(mr.quality_id),2) quality_rating
   round(avg(mr.friendly_id),2) friendly_rating,
   round(avg(mr.professional_id),2) professional_rating
from mechanic m, mechanic_rating mr, rating r
where m.mechanic_id in (1)
and m.mechanic_id = mr.mechanic_id
and mr.quality_id = r.rating_id(+) <-- these cause issues
and mr.friendly_id = r.rating_id(+) <-- these cause issues
and mr.professional_id = r.rating_id(+) <-- these cause issues
group by mechanic_id
评级表

|rating_id|rating  |
|1        |terrible|
|2        |bad     |
etc.
机械师评分表

|mechanic_rating_id|mechanic_id|quality_id|friendly_id|professional_id|
|unique auto inc   |FK         |
质量id、友好id和专业id都应该是评级表中评级id的外键


如果我从查询中去掉(+),我得到的结果为零,所以我认为问题是我需要进行左外连接。如果您需要更多信息,请告诉我。

这将解决(+)的问题;使用左外部联接意味着即使右表中没有元素,也将包括左表中的所有内容。同样,右侧所有内容的列(如果不匹配)将为空

select m.mechanic_id, 
   m.mechanic_name, 
   m.city, 
   m.state, 
   count(mr.mechanic_id) as num_ratings, 
   round(avg(mr.quality_id),2) quality_rating
   round(avg(mr.friendly_id),2) friendly_rating,
   round(avg(mr.professional_id),2) professional_rating
FROM mechanic m LEFT OUTER JOIN mechanic_rating mr ON(m.mechanic_id = mr.mechanic_id) 
LEFT OUTER JOIN rating r ON(mr.quality_id = r.rating_id AND 
mr.friendly_id = r.rating_id AND mr.professional_id = r.rating_id) 
WHERE m.mechanic_id in (1) GROUP BY mechanic_id

这将解决(+)的问题;使用左外部联接意味着即使右表中没有元素,也将包括左表中的所有内容。同样,右侧所有内容的列(如果不匹配)将为空

select m.mechanic_id, 
   m.mechanic_name, 
   m.city, 
   m.state, 
   count(mr.mechanic_id) as num_ratings, 
   round(avg(mr.quality_id),2) quality_rating
   round(avg(mr.friendly_id),2) friendly_rating,
   round(avg(mr.professional_id),2) professional_rating
FROM mechanic m LEFT OUTER JOIN mechanic_rating mr ON(m.mechanic_id = mr.mechanic_id) 
LEFT OUTER JOIN rating r ON(mr.quality_id = r.rating_id AND 
mr.friendly_id = r.rating_id AND mr.professional_id = r.rating_id) 
WHERE m.mechanic_id in (1) GROUP BY mechanic_id

您需要学习并使用ANSI-92标准语法来执行连接谓词。使用ANSI-92,您的查询将写为

 select m.mechanic_id,  m.mechanic_name, m.city,
     m.state, count(mr.mechanic_id) num_ratings, 
     round(avg(mr.quality_id),2) quality_rating   
     round(avg(mr.friendly_id),2) friendly_rating,   
     round(avg(mr.professional_id),2) professional_rating
from mechanic m
   Left Join mechanic_rating mr
       On mr.mechanic_id = m.mechanic_id
   Left Join rating r 
       On r.rating_id = mr.quality_id
           And r.rating_id = mr.friendly_id
           And r.rating_id = mr.friendly_id 
 where m.mechanic_id in (1)
 group by mechanic_id
注:(1)指的是什么??您是否试图将此限制为

其中m.mechanical_id=1?

您需要学习并使用ANSI-92标准语法来执行连接谓词。使用ANSI-92,您的查询将写为

 select m.mechanic_id,  m.mechanic_name, m.city,
     m.state, count(mr.mechanic_id) num_ratings, 
     round(avg(mr.quality_id),2) quality_rating   
     round(avg(mr.friendly_id),2) friendly_rating,   
     round(avg(mr.professional_id),2) professional_rating
from mechanic m
   Left Join mechanic_rating mr
       On mr.mechanic_id = m.mechanic_id
   Left Join rating r 
       On r.rating_id = mr.quality_id
           And r.rating_id = mr.friendly_id
           And r.rating_id = mr.friendly_id 
 where m.mechanic_id in (1)
 group by mechanic_id
注:(1)指的是什么??您是否试图将此限制为

其中m.Mechanical_id=1?

您的评分是独立的和正交的,对吗?您需要在不同别名中使用相同的评级表:

from mechanic m
   Left Join mechanic_rating mr
       On mr.mechanic_id = m.mechanic_id
   Left Join rating r_quality
       On r_quality.rating_id = mr.quality_id
   Left Join rating r_friendly
       On r_friendly.rating_id = mr.friendly_id
   Left Join rating r_professional
       On r_professional.rating_id = mr.professional_id
正如你所做的那样,将它们结合起来,只需过滤掉独立评级不完全相同的所有行,这可能是影响你看到的结果的另一个因素

虽然外键是同一个表,但每个键都是独立的,因此需要“角色”才能使表发挥作用

但是,由于在选择列表中不使用任何评级列,因此实际上可以完全忽略它们:

select m.mechanic_id, 
   m.mechanic_name, 
   m.city, 
   m.state, 
   count(mr.mechanic_id) as num_ratings, 
   round(avg(mr.quality_id),2) quality_rating
   round(avg(mr.friendly_id),2) friendly_rating,
   round(avg(mr.professional_id),2) professional_rating
from mechanic m, mechanic_rating mr
where m.mechanic_id in (1)
and m.mechanic_id = mr.mechanic_id
group by mechanic_id
请注意,您还可以修复旧样式联接:

from mechanic m, mechanic_rating mr, rating r_quality, rating r_friendly, rating r_professional
where m.mechanic_id in (1)
and m.mechanic_id = mr.mechanic_id
and mr.quality_id = r_quality.rating_id(+)
and mr.friendly_id = r_friendly.rating_id(+)
and mr.professional_id = r_professional.rating_id(+)
group by mechanic_id

你的评分是独立和正交的,对吗?您需要在不同别名中使用相同的评级表:

from mechanic m
   Left Join mechanic_rating mr
       On mr.mechanic_id = m.mechanic_id
   Left Join rating r_quality
       On r_quality.rating_id = mr.quality_id
   Left Join rating r_friendly
       On r_friendly.rating_id = mr.friendly_id
   Left Join rating r_professional
       On r_professional.rating_id = mr.professional_id
正如你所做的那样,将它们结合起来,只需过滤掉独立评级不完全相同的所有行,这可能是影响你看到的结果的另一个因素

虽然外键是同一个表,但每个键都是独立的,因此需要“角色”才能使表发挥作用

但是,由于在选择列表中不使用任何评级列,因此实际上可以完全忽略它们:

select m.mechanic_id, 
   m.mechanic_name, 
   m.city, 
   m.state, 
   count(mr.mechanic_id) as num_ratings, 
   round(avg(mr.quality_id),2) quality_rating
   round(avg(mr.friendly_id),2) friendly_rating,
   round(avg(mr.professional_id),2) professional_rating
from mechanic m, mechanic_rating mr
where m.mechanic_id in (1)
and m.mechanic_id = mr.mechanic_id
group by mechanic_id
请注意,您还可以修复旧样式联接:

from mechanic m, mechanic_rating mr, rating r_quality, rating r_friendly, rating r_professional
where m.mechanic_id in (1)
and m.mechanic_id = mr.mechanic_id
and mr.quality_id = r_quality.rating_id(+)
and mr.friendly_id = r_friendly.rating_id(+)
and mr.professional_id = r_professional.rating_id(+)
group by mechanic_id

我认为您将
左外部联接
左联接
混淆了。两个查询的结果是相同的。外部连接不是隐含的吗?如果我没有错的话(我可能是错的),我认为
左连接
就是您上面描述的,而
左外部连接
只是左表中不匹配的部分。左连接=左外部连接;如果指定了LEFT,则表示OUTTER。同样,如果没有指定LEFT,JOIN=INNER JOIN。我认为您将
LEFT OUTER JOIN
LEFT JOIN
混淆了。两个查询的结果是相同的。外部连接不是隐含的吗?如果我没有错的话(我可能是错的),我认为
左连接
就是您上面描述的,而
左外部连接
只是左表中不匹配的部分。左连接=左外部连接;如果指定了LEFT,则表示OUTTER。同样,如果没有指定LEFT,JOIN=internaljoin。我在我的应用程序中使用了一个包含1个或多个id的变量。我只是用“1”来测试我的查询。我假设这个变量是一个表变量??否则,您不需要进行分组…我正在我的应用程序中使用一个包含1个或多个id的变量。我只是用“1”来测试我的查询。我假设这个变量是一个表变量??否则,你不需要做一个小组由。。。