2012-06-21 84 views
1

我试图在MySQL SELECT语句中包含子查询来组装产品链接,当与该链接关联的产品ID可能不再存在时。当该产品ID不存在时,子查询找不到任何结果,并且整个行从最终结果中被省略。无论如何,我希望该行能够被返回(NULL值会很好)。当子查询匹配没有结果时,MySQL子查询忽略整行

SELECT s.field_a, s.field_b, s.field_c, 
    (SELECT CONCAT('/', sma.name_link, '/', smo.name_link, '.html?pid=', spr.id) 
     FROM sales_products AS spr, sales_sections AS see, 
      sales_models AS smo, sales_manufacturers AS sma 
     WHERE sse.id = spr.sales_section_id AND smo.id = sse.sales_model_id 
      AND smo.sales_manufacturer_id = sma.id 
      AND spr.id = s.sales_product_id 
    ) AS product_link 
    FROM sales_order_items AS s, sales_products AS p 
    WHERE s.order_id = 100 AND p.id = s.sales_product_id 
    ORDER BY shipment_id, sales_order_item_id 

我已经搜索了很长一段时间,但我只是没有设法将这一块拼凑在一起。我期待着可以提供的任何形式的反馈或解决方案。

回答

0

我在您的查询的任何位置没有看到product_id列参考,因此我打算假定您的意思是它的sales_product_id列的值不匹配id值sales_product表。

我不认为“缺失行”的问题与SELECT列表中的子查询有关;我相信它与INNER JOIN到sales_product表有关。我建议你将它改为左外连接。

SELECT s.field_a 
    , s.field_b 
    , s.field_c 
    , (SELECT CONCAT('/',sma.name_link,'/',smo.name_link,'.html?pid=',spr.id) 
      FROM sales_products spr 
      JOIN sales_sections see ON sse.id = spr.sales_section_id 
      JOIN sales_models smo ON smo.id = sse.sales_model_id 
      JOIN sales_manufacturers sma ON sma.id = smo.sales_manufacturer_id 
     WHERE spr.id = s.sales_product_id 
     ORDER BY 1 LIMIT 1 
     ) AS product_link 
    FROM sales_order_items s 
    LEFT 
    JOIN sales_products p ON p.id = s.sales_product_id 
WHERE s.order_id = 100 
ORDER BY shipment_id, sales_order_item_id 

注:在SELECT列表(别名为product_link)子查询的问题,是该语句将抛出一个异常,如果(何时?)子查询返回不止一行。除非你有某种保证永远不会这么做,至少你可以在它上面打一个ORDER BY 1 LIMIT 1,或者在CONCAT周围打一个MAX聚合(这样它就是确定的)。

使用表别名限定ORDER BY子句中的列引用是防止潜在的“模糊列”异常的保护,这也是一个非常好的主意。我发现所有的列引用都是合格的,这是一件非常好的事情。

您可能还注意到我重新格式化了原始查询,并且引入了JOIN关键字(代替逗号),并将连接谓词从WHERE子句移到了ON子句中。我发现这使得语句更容易阅读,并且更容易调试。它还让你指定一个OUTER JOIN。

+0

谢谢你,斯宾塞。这完美地完成了这个技巧。看起来你明白我想要完成的事情(为了简化示例,我从查询中删除了很多内容)。 同时也感谢您与我分享更多的想法和最佳实践。我真的很感激。 – James

+0

答复完毕后,我点击复选框接受答案。我想这就是你的建议?请让我知道是否还有更多我错过的东西。 – James

-1

您可能想要在查询中尝试使用UNION,或者如果值为空,甚至可以使用IF sql条件来设置NULL。

希望有所帮助。

+0

谢谢你的建议。我无法将工作解决方案放在一起,但这可能是由于我相对缺乏经验。 – James