Mysql在where子句中与多个case语句连接

时间:2014-02-07 14:42:56

标签: mysql sql join

我有两张桌子。一个是engine4_users,另一个是engine4_user_fields_valuesengine4_users表包含id, email, password,displayname。它与one to many表有engine4_user_fields_values个关系。 engine4_user_fields_values表看起来像

enter image description here

其中item_id是users表的user_id。现在您可以看到,在此表中,field_id对于一个项ID也可以有很多值。

现在我想从这两个表中选择数据,有时我需要value列的值,有时我需要将value列放在基于field_id的where条件中。 例如,请参阅我的查询

SELECT 
`eu`.`user_id`, `eu`.`displayname`, 
GROUP_CONCAT(
                   CASE WHEN eufv.field_id = 19 THEN eufv.value END
                 ) AS city,
    GROUP_CONCAT(
        CASE WHEN eufv.field_id = 15 THEN eufv.value END
        )AS interests

FROM 
     `engine4_users` AS `eu`
    INNER JOIN 
     `engine4_user_fields_values` AS `eufv` 
    ON 
    eu.user_id = eufv.item_id 
    WHERE 
     (eu.username LIKE '%hameed%' OR eu.email LIKE '%hameed%' OR eu.displayname LIKE '%hameed%') 
   GROUP BY 
`eu`.`user_id`;

此查询按用户获取数据组,并以逗号分隔获取field_id 15和16的值。现在我想在第二个表上添加更多条件以过滤掉结果。

例如我想把条件放在field_id 6上,即生日那个人的年龄在某个范围内,而field_id 5则是3的值。但是当我把下面的查询时

SELECT 
`eu`.`user_id`, `eu`.`displayname`, 

GROUP_CONCAT(
                   CASE WHEN eufv.field_id = 19 THEN eufv.value END
                 ) AS city,
    GROUP_CONCAT(
        CASE WHEN eufv.field_id = 15 THEN eufv.value END
        )AS interests
    FROM 
     `engine4_users` AS `eu`
    INNER JOIN 
   `engine4_user_fields_values` AS `eufv` 
    ON 
   eu.user_id = eufv.item_id 
    WHERE 
    (eu.username LIKE '%hameed%' OR eu.email LIKE '%hameed%' OR eu.displayname LIKE '%hameed%') 
   AND 
   (FLOOR(DATEDIFF(CURDATE(),CASE WHEN eufv.field_id = 6 THEN eufv.`value` END ) / 365) >= '20') 
   AND 
   (FLOOR(DATEDIFF(CURDATE(),CASE WHEN eufv.field_id = 6 THEN eufv.`value` END ) / 365) <= '29') 
  GROUP BY 
`eu`.`user_id`;

此查询给出了结果,但在这种情况下,我没有得到列城市和兴趣列的值。它们在结果集中是空的。如果我在where子句中再添加一个条件

AND ((CASE WHEN eufv.field_id = 5 THEN eufv.`value` END)  = '3') 

哪个好,并与记录一起映射。但在这种情况下,结果集是空的。

我尽力解释我的问题。因此,请指导我如何撰写此查询或让我知道如果我无法传达我的问题。

最好的问候

1 个答案:

答案 0 :(得分:0)

首先:你在没有ELSE的情况下使用CASE WHEN。因此,例如,以下条件对于所有eufv.field_id&lt;&gt;而言都是假的。 6,因为CASE评估为NULL,而不是> = 20。

(FLOOR(DATEDIFF(CURDATE(),CASE WHEN eufv.field_id = 6 THEN eufv.`value` END ) / 365) >= '20') 
AND 

其次:当然,缩小标准时,记录的记录会减少。也许你想要所有engine4_users并且只在满足你的标准时才从engine4_user_fields_values中添加数据?这将是一个外部联接:

FROM `engine4_users` AS `eu`
LEFT JOIN `engine4_user_fields_values` AS `eufv` 
ON 
  eu.user_id = eufv.item_id AND 
  (FLOOR(DATEDIFF(CURDATE(),CASE WHEN eufv.field_id = 6 THEN eufv.`value` END ) / 365) >= '20') 
  ...
WHERE 
  (eu.username LIKE '%hameed%' OR eu.email LIKE '%hameed%' OR eu.displayname LIKE '%hameed%') 

确保在外部连接时,ON子句中的表ne4_user_fields_values具有所有条件,而不是WHERE子句。