具有多个连接的SQL查询仅在最终连接时返回第一个结果

时间:2014-05-03 22:49:58

标签: php mysql sql join

所以我有一个准备好的SQL查询(下面),根据用户的ID将4个表连接在一起。然而,最终关系是一对多(用户可以拥有多个技能),因此我需要返回技能ID等于用户ID的所有行。目前只返回与freelancer_skill表中的用户ID匹配的第一行。如何让所有行返回?

SELECT 
    u.user_id, u.firstname, u.lastname, u.email, u.bio, u.portfolio, u.location, u.time_joined, u.image_location, 
    f.freelancer_id, f.jobtitle, f.priceperhour, 
    ut.*,
    ft.testimonial, ft.testimonial_source,
    fs.skill, fs.skill_rating
FROM ((((users AS u
    LEFT JOIN freelancers AS f
ON u.user_id = f.freelancer_id)
    LEFT JOIN user_types AS ut
ON u.user_id = ut.user_type_id)
    LEFT JOIN freelancer_testimonials AS ft
ON u.user_id = ft.testimonial_id)
    LEFT JOIN freelancer_skills AS fs
ON u.user_id = fs.skill_id)
WHERE 
    u.confirmed = :confirmed
AND u.user_id = :userID
AND ut.user_type = :userType
AND u.granted_access = :grantedAccess

修改

更新了用户类型WHERE子句移入连接的代码:

SELECT 
    u.firstname, u.lastname, u.email, u.bio, u.portfolio, u.location, u.time_joined, u.image_location, 
    f.jobtitle, f.priceperhour, 
    ut.user_type,
    ft.testimonial, ft.testimonial_source,
    fs.skill, fs.skill_rating
FROM ((((" . DB_NAME . ".users AS u
    LEFT JOIN " . DB_NAME . ".freelancers AS f
ON u.user_id = f.freelancer_id)
    LEFT JOIN " . DB_NAME . ".user_types AS ut
ON u.user_id = ut.user_type_id AND ut.user_type = :userType)
    LEFT JOIN " . DB_NAME . ".freelancer_testimonials AS ft
ON u.user_id = ft.testimonial_id)
    RIGHT JOIN " . DB_NAME . ".freelancer_skills AS fs
ON u.user_id = fs.skill_id)
WHERE 
    u.confirmed = :confirmed
AND u.user_id = :userID
AND u.granted_access = :grantedAccess

要获取结果,我使用fetch(下面)。我尝试过使用fetchALL,它会返回用户持有的每项技能,但也返回每项技能的重复数据。

$results->execute();
$user = $results->fetch(PDO::FETCH_ASSOC);
return $user;

这是一个SQLFiddle:http://sqlfiddle.com/#!2/d7bb3/4

2 个答案:

答案 0 :(得分:0)

您的过滤器位置错误。您正在向user_types声明左连接,但正在where子句中对该表进行过滤。这使它成为一个隐含的内部联接。移动

and ut.user_type = :userType

遵循这个:

LEFT JOIN user_types AS ut ON u.user_id = ut.user_type_id

这可能是您的问题的原因,但即使不是,您仍然会在where子句中使用该过滤器获得意外结果。

答案 1 :(得分:-1)

更改联接的顺序。交换Users表和freelancer_skills表。 - 这显然不起作用。

也许尝试这样的事情。如果你想为一个人列出一百个技能,那就不理想了。

SELECT  
u.firstname, 
u.lastname, 
u.email, u.bio, u.portfolio, u.location, u.time_joined, u.image_location,
f.jobtitle, f.priceperhour,
ut.user_type,
ft.testimonial, ft.testimonial_source,
count(case when fs.skill = 'HTML5' then 1 end) as HTML5, 
count(case when fs.skill = 'CSS3' then 1 end) as CSS3, 
count(case when fs.skill = 'PHP' then 1 end) as PHP, 
fs.skill_rating
FROM 
(
  (
    (
      (
       users AS u
  LEFT JOIN freelancers AS f ON 
  u.user_id = f.freelancer_id
  )
  LEFT JOIN user_types AS ut ON 
  u.user_id = ut.user_type_id AND 
  ut.user_type = 'developer'
)
LEFT JOIN freelancer_testimonials AS ft ON 
u.user_id = ft.testimonial_id
)
RIGHT JOIN freelancer_skills AS fs ON 
u.user_id = fs.skill_id
 )
  WHERE
  u.confirmed = '1'
  AND u.user_id = '3'
  AND u.granted_access = '1'
  group by 
  u.firstname, 
  u.lastname, 
  u.email, u.bio, u.portfolio, 
  u.location, 
  u.time_joined, u.image_location,
  f.jobtitle, f.priceperhour,
  ut.user_type,
  fs.skill_rating