1

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

+----+--------------+-------+----------------+------------+
| 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 需要返回行中未设置的引用行值......在同一个结果集中。

我需要为某些领域做这件事。所以假设我想选择product_nameID 3 的字段。它应该zzzzbulk_reference字段设置为 2 时返回,所以它应该从行 ID=2 中获取值。

我怎样才能只用 MySQL 做到这一点?

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

更新:

到目前为止发布了所有答案,我收到错误消息 #1054Unknown 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=BlackBerry 上有一部 BlackBerry 手机。但在另一行 (ID=2),我们有同一部手机的批量包装,因此 ID=2 & product_name=blank & bulk_reference=1。我们需要从 bulk_referenced 行返回产品的名称,因为它是相同的产品,只是在散装包装中。

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

4

3 回答 3

1

可以使用 LEFT JOIN 获得结果,(假设我们保证该id列在 products 表上是唯一的):

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

要从行 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
于 2013-02-11T19:44:58.227 回答
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

祝你好运。

于 2013-02-11T19:06:22.873 回答
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,它将从连接表中获取。

于 2013-02-11T19:08:22.893 回答