MySQL从同一个表中的另一个引用行返回值

时间:2013-02-11 19:03:45

标签: mysql

假设我的表格看起来像这样:

+----+--------------+-------+----------------+------------+
| id | product_name | price | bulk_reference | bulk_count |
+----+--------------+-------+----------------+------------+
| 1  | xxxx         | 11.99 | 0              | 0          |
+----+--------------+-------+----------------+------------+
| 2  | zzzz         | 22.99 | 0              | 0          |
+----+--------------+-------+----------------+------------+
| 3  |              |       | 2              | 10         |
+----+--------------+-------+----------------+------------+

我可以选择所有产品等,没问题。但是 - 我需要做的是返回所有产品,但行WHERE bulk_reference> 0需要返回行中未设置的引用行值...在同一结果集中。

我需要为某些领域做这件事。所以我要说我想为ID 3选择product_name字段。它应该返回zzzz,因为bulk_reference字段设置为2,所以应该从行ID = 2获取值

我怎样才能使用MySQL?

======================================

更新:

到目前为止发布了所有答案我收到错误消息#1054 Unknown column 'p.bulk_reference' in 'field list'.我不知道为什么会发生这种情况......

这是对其中一个答案的改编:

SELECT p.id , 
   IF(p.bulk_reference>0,r.sales_price,p.sales_price) AS sales_price 
   , p.bulk_reference 
   , p.bulk_count 
FROM products_attribs_cz p 
LEFT JOIN products_attribs_cz r ON r.id = p.bulk_reference 
AND p.bulk_reference > 0 
WHERE p.id=166; 

然而,无论我尝试过什么解决方案,我总是得到错误...

此表中的ID是唯一的。正在选择的字段会更改并动态生成。总有一个结果。不是几个。我总是选择一个独特的行,但是,它是一个批量产品包。例如,我们在行ID = 1& PRODUCT_NAME =黑莓。但是在另一行(ID = 2)我们有一个同一部手机的批量包,所以ID = 2& product_name = blank& bulk_reference = 1。我们需要从bulk_referenced行返回产品名称,因为它是相同的产品,仅在批量包装中。

(我们的想法是,批发商可以获得批量订单的折扣。因此,如果订购1手机他们获得正常价格,如果他们订购大部分10部手机,他们可以获得20%的折扣)

3 个答案:

答案 0 :(得分:1)

可以使用LEFT JOIN获得结果,(假设我们保证产品表上的id列是UNIQUE):

SELECT p.id
     , IF(p.bulk_reference>0,r.product_name,p.product_name) AS product_name
     , p.price
     , p.bulk_reference
     , p.bulk_count
  FROM products p
  LEFT
  JOIN products r
    ON r.id = p.bulk_reference AND p.bulk_reference > 0

LEFT JOIN表示返回左侧表格中的所有行,以及右侧表格中的任何“匹配”行。在这种情况下,如果bulk_reference列的值大于零,我们只需要一个“匹配”行,因此我们可以在ON子句的谓词中包含该条件。

“技巧”是在SELECT列表中使用条件测试。如果bulk_reference列大于零,我们从父行返回名称,否则,我们从当前行返回值。

(如果我们不保证id是唯一的,则需要修改该查询以保证返回的结果集与规范匹配。)

获得等效结果的另一种方法是在SELECT列表中使用相关子查询。 (这不是最有效的方法,但它适用于返回的少量行。)

SELECT p.id
     , IF(p.bulk_reference > 0,
           ( SELECT r.product_name
               FROM products r
              WHERE r.id = p.bulk_reference
              ORDER BY r.id
              LIMIT 1
           ), p.product_name
       ) AS product_name
     , p.price
     , p.bulk_reference
     , p.bulk_count
  FROM products p

这将做的是:如果bulk_reference列值大于零,MySQL将执行子查询以从引用的行返回product_name值。否则(即如果bulk_reference为空或不大于零,则将返回存储在该行的product_name列中的值。


注意:上面的查询只从引用的行中获取product_name的值;他们不对引用的行进行测试,并考虑到实际从另一个父行检索该引用行上的product_name。

考虑一下这组行:

  id  product_name  price  bulk_reference
  --  ------------  -----  --------------
   1  fee           11.99  0             
   2  fi            22.99  0             
   3  fo            25.99  2
   4  fum           28.99  3

要将row id = 4的product_name作为“fi”返回,而不是“fo”......

SELECT p.id
     , IF(p.bulk_reference>0,
         IF(q.bulk_reference>0,
           IF(r.bulk_reference>0,s.product_name,r.product_name),
           q.product_name),
         p.product_name
       ) AS product_name
     , p.price
     , p.bulk_reference
     , p.bulk_count
  FROM products p
  LEFT
  JOIN products q
    ON q.id = p.bulk_reference AND q.bulk_reference > 0
  LEFT
  JOIN products r
    ON r.id = q.bulk_reference AND r.bulk_reference > 0
  LEFT
  JOIN products s
    ON s.id = r.bulk_reference AND s.bulk_reference > 0

答案 1 :(得分:0)

针对您的具体示例尝试类似的内容:

SELECT P2.Product_Name
FROM Products P
  INNER JOIN Products P2 ON P.Bulk_Reference = P2.Id
WHERE P.Id = 3

并返回所有产品名称:

SELECT CASE 
    WHEN P.Bulk_Reference = 0 THEN P.Product_Name 
    ELSE COALESCE(P2.Product_Name,'Unknown') END Product
FROM Products P
  LEFT JOIN Products P2 ON P.Bulk_Reference = P2.Id

如果Bulk_Reference> 0 AND Product_Name为NULL,我添加了Unknown。假设Product_Name为NULL且不为空。如果为空,请添加

COALESCE(NULLIF(P2.Product_Name,''),'Unknown')

- 编辑

我没有看到您想要返回值为空的参考字段中的所有行值。上面的查询将以相同的方式工作 - 只需添加您的字段。

SELECT P.Id, 
    CASE WHEN P.Bulk_Reference = 0 THEN P.Product_Name 
    ELSE COALESCE(P2.Product_Name,'Unknown') END Product_Name, 
    CASE WHEN P.Bulk_Reference = 0 THEN P.Price 
    ELSE COALESCE(P2.Price,'Unknown') END Price,
    P.Bulk_Reference,
    CASE WHEN P.Bulk_Reference = 0 THEN P.Bulk_Count
    ELSE COALESCE(P2.Bulk_Count,0) END Bulk_Count
FROM Products P
  LEFT JOIN Products P2 ON P.Bulk_Reference = P2.Id
祝你好运。

答案 2 :(得分:0)

你可以这样做

select
  m.id,
  IF(m.product_name is null,l.product_name,m.product_name) as ProductName,
  m.bulk_reference
from mytable as m
  LEFT JOIN mytable as l ON l.id = m.bulk_reference

如果product_name为null,则将从连接表中获取。