2013-03-14 44 views
0

我有以下查询,我用它来根据software_id和级别过滤行。 我已经把条件放在ON-Clause中,因为我仍然希望返回行,JobadvertsSoftware表中没有相应的行。将条件与AND合并到Mysql ON子句中

SELECT `Jobadvert`.`id` FROM `jobadverts` AS `Jobadvert` 

LEFT JOIN `users` AS `User` ON (`Jobadvert`.`user_id` = `User`.`id`) 

LEFT JOIN `jobadverts_softwares` AS `JobadvertsSoftware_0` ON 
(`Jobadvert`.`id` = 'JobadvertsSoftware_0.jobadvert_id' AND 
(`JobadvertsSoftware_0`.`software_id` = '32' AND 
`JobadvertsSoftware_0`.`level` IN ('1', 4))) 


WHERE `Jobadvert`.`active` = 1 AND `User`.`premium` = '1' AND 
Jobadvert`.`department_id` = (5) 

GROUP BY `Jobadvert`.`id` 

问题是,它还返回JobadvertsSoftware行,其中级别是例如, 2 同样,如果我将它放在WHERE子句中,它将过滤掉没有JobadvertsSoftware不应该执行的行。 如何告诉MySQL返回Jobadvert的所有行,其中给定的software_id和级别匹配或为NULL?

+0

如果您使用INNER JOIN而不是OUTER JOIN,那会给你想要的吗? – Melanie 2013-03-14 14:38:55

+1

建议使用较短的别名 – ldgorman 2013-03-14 14:39:28

+0

在您的WHERE子句中放置“level” – ldgorman 2013-03-14 14:40:54

回答

0

试试这个:

SELECT `Jobadvert`.`id`, `JobadvertsSoftware_0`.`level` 
FROM `jobadverts` AS `Jobadvert` 

LEFT JOIN `users` AS `User` ON (`Jobadvert`.`user_id` = `User`.`id`) 

INNER JOIN `jobadverts_softwares` AS `JobadvertsSoftware_0` ON 
(`Jobadvert`.`id` = 'JobadvertsSoftware_0.jobadvert_id' AND 
(`JobadvertsSoftware_0`.`software_id` = '32' AND 
`JobadvertsSoftware_0`.`level` IN ('1', 4))) 


WHERE `Jobadvert`.`active` = 1 AND `User`.`premium` = '1' AND 
Jobadvert`.`department_id` = (5) 

GROUP BY `Jobadvert`.`id` 

Saludos!

+0

感谢您的建议。使用INNER JOIN所有 – forellenfuerst 2013-03-14 14:58:01

0

试试这个(这是一个有点不清楚,如果某些字段上串的数值,它可能会被纠正):

SELECT distinct(`Jobadvert`.`id`) FROM `jobadverts` AS `Jobadvert` 
LEFT JOIN `users` AS `User` ON (`Jobadvert`.`user_id` = `User`.`id`) 
LEFT JOIN `jobadverts_softwares` AS `JobadvertsSoftware_0` 
ON `Jobadvert`.`id` =  `JobadvertsSoftware_0.jobadvert_id` 
WHERE 
`Jobadvert`.`active` = 1 
AND `User`.`premium` = '1' 
AND Jobadvert`.`department_id` = (5) 
AND JobadvertsSoftware_0`.`software_id` = '32' 
AND (`JobadvertsSoftware_0`.`level` IN (1, 4) OR `JobadvertsSoftware_0`.`level` is NULL) 
+0

你的语法,将不返回任何行断中途上:ON'Jobadvert'.'id' ='JobadvertsSoftware_0.jobadvert_id” – 2013-03-14 15:04:39

-1

试试这个:

SELECT j.id 
FROM jobadverts j 
LEFT JOIN User u ON (j.user_id = u.id) 
LEFT JOIN jobadverts_softwares AS js ON 
(j.id = js.jobadvert_id) 
WHERE j.active = 1 
    AND u.premium = '1' 
    AND j.department_id = (5) 
    AND js.software_id` = '32' 
    AND js.level IN ('1', 4))) 

你不会需要一个GROUP BY除非以某种方式汇总数据。

+0

确保你在弯角引号包围表名和纠正它'用户'我喜欢缩短的别名,但更容易阅读。 – 2013-03-14 16:02:01

0

假设你的ON子句中的水平参数不需要的连接,你可以做一个嵌套的SELECT您的软件表就一目了然了你不首先需要的数据:

SELECT * FROM jobadverts_softwares 
WHERE 
    (`software_id` = 32 OR `software_id` IS NULL) --Select all software_id that are 32 or null 
AND 
    `level` IN (1, 4) 

然后你就可以将本作中,你的主要的SQL查询嵌套语句,这样你才能加入其上在你的左边过滤数据结合,但保留您所需要的任何空值:

SELECT `Jobadvert`.`id` 
FROM `jobadverts` AS `Jobadvert` 

LEFT JOIN `users` AS `User` 
ON `Jobadvert`.`user_id` = `User`.`id` 

LEFT JOIN 
( --Software Subquery 
    SELECT `jobadvert_id`, `level` FROM jobadverts_softwares 
    WHERE 
     (`software_id` = 32 OR `software_id` IS NULL) --Select all software_id that are 32 or null 
    AND 
     `level` IN (1, 4) 
) AS `software_subquery` 

ON `Jobadvert`.`id` = `software_subquery`.`jobadvert_id` 

WHERE 
    `Jobadvert`.`active` = 1 
AND 
    `User`.`premium` = '1' 
AND 
    `Jobadvert`.`department_id` = 5 

ORDER BY `Jobadvert`.`id` --Changed GROUP BY to ORDER BY as not needed 

这是未经测试,但尝试一下,看看是否这将有所帮助。