1

当与该链接关联的产品 ID 可能不再存在时,我试图在 MySQL SELECT 语句中包含一个子查询来组装产品链接。当该产品 ID 不存在时,子查询未找到任何结果,并且从最终结果中省略了整行。我希望无论如何都要返回该行(使用 NULL 就可以了)。

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

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

4

2 回答 2

0

我在您的查询中的任何地方都没有看到product_id列引用,因此我假设您的意思是它的列是具有与 sales_product 表中的值sales_product_id不匹配的值的列。id

我认为“缺失行”的问题与 SELECT 列表中的子查询无关;我相信这与 sales_product 表的 INNER JOIN 有关。我建议您将其更改为 LEFT OUTER JOIN。

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。

于 2012-06-21T20:46:33.187 回答
-1

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

希望有帮助。

于 2012-06-21T18:41:03.070 回答