2011-03-13 87 views
2

我有两个表加入user_id。在下面的查询中,我正在比较table_two中的act_val,以确保它位于或等于来自table_one的min_valmax_val之间。但是有时table_one中的user_id在table_two中找不到。在这些情况下,我希望act_val被视为0,并限定table_one的min_val较低。那可能吗?怎么会这样?如何将NULL值视为0从MySQL

SELECT tb1.id FROM table_one tb1 
INNER JOIN table_two tb2 WHERE 
    tb1.min_val <= tb2.act_val AND tb1.min_val >= tb2.act_val 
    AND tb2.user_id = tb1.user_id 
GROUP BY ad.id; 

回答

5

您需要在左边的USER_ID链接JOIN条件(ON子句),并在WHERE子句(过滤器)休息。 tb2.act_val在缺失时被视为0,使用IFNULL。我也修正了你的第二个条件,它应该是    tb1。 max _val> =     not     tb1。 分钟 _val> =

 SELECT tb1.id 
     FROM table_one tb1 
    LEFT JOIN table_two tb2 ON tb2.user_id = tb1.user_id 
     WHERE tb1.min_val <= IFNULL(tb2.act_val,0) 
     AND tb1.max_val >= IFNULL(tb2.act_val,0) 
    GROUP BY tb1.id; 

LEFT JOIN

如果没有用于在ON右表中没有匹配的行或USING部分在左连接,设置为NULL所有列的行用于右表。你可以利用这一点来在表中查找有没有对应的另一个表行:

+0

我实现这一点,但左加入了我的查询需要几分钟来计算(100X慢)。我还有其他的内部联接和条件。这是正常的吗?我可以混合LEFT JOIN和INNER JOIN吗? – Kyle 2011-03-13 21:05:17

+0

你可以混合内部/左边的连接,但你必须确保它按正确的顺序完成。不仅如此,LEFT JOINs意味着即使没有要在右侧匹配的记录,也要从左侧开始记录所有记录 - 根据定义,这会增加处理其余查询记录的次数 – RichardTheKiwi 2011-03-13 21:20:37

0

您可以使用IFNULL(tbl2.act_val, 0)

0
  1. 更换inner joinleft join
  2. 使用coalesce(tb2.act_val, 0),而不是tb2.act_val

PS同样 - 您的查询看起来不正确,因为你指的是未定义的表广告。

0

可以使用COALESCE功能:

WHERE COALESCE(tb1.min_val, 0) <= tb2.act_val COALESCE(tb1.min_val, 0) >= tb2.act_val 
1

使用外连接(LEFT在下面的例子)来获取所有的TABLE1记录可能会或可能不会有匹配TABLE2中的user_id值。然后构建WHERE子句来筛选下来设置为你想要的记录:

SELECT tb1.id 
    FROM table_one tb1 
LEFT JOIN table_two tb2 ON tb2.user_id = tb1.user_id 
    WHERE tb2.act_val BETWEEN tb1.min_val AND tb1.max_val 
     OR tb1.min_val < 0 
GROUP BY tb1.id 
+0

几乎与我的记录相同即将发布,只有在我的情况下,它会像'... ON tb2.user_id = tb1.user_id AND tb2.act_val BETWEEN tb1.min_val AND tb1.max_val WHERE tb2.user_id IS NULL OR tb1.min_val <0 '。你的一个很好的小窍门是使它更简洁。 – 2011-03-13 21:46:10

相关问题