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_nameそれでは、ID 3のフィールドを選択したいとしましょう。フィールドが 2 に設定されているため、返さzzzzれるbulk_referenceはずなので、行 ID=2 から値を取得する必要があります。

MySQL のみでこれを行うにはどうすればよいですか?

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

アップデート:

これまでに投稿されたすべての回答で、エラーメッセージ #1054 が表示されますUnknown column 'p.bulk_reference' in 'field list'.。なぜこれが起こるのかわかりません...

これは、投稿された回答の1つを適応させたものです。

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 はこのテーブル内で一意です。選択されているフィールドが変化し、動的に生成されます。結果は常に 1 つだけです。いくつかではありません。私は常に一意の行を選択していますが、これは製品のバルク パッケージです。たとえば、行 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

idLEFT JOIN を使用して結果を取得することは可能です ( products テーブルで列が 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 列の値が 0 より大きい場合にのみ「一致する」行が必要なので、その条件をON句の述語に含めることができます。

「トリック」は、SELECT リストで条件付きテストを使用することです。bulk_reference 列が 0 より大きい場合は、親行から名前を返します。それ以外の場合は、現在の行から値を返します。

(一意であるという保証がない場合は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列の値が 0 より大きい場合、MySQL はサブクエリを実行して、参照された行から値を返しますproduct_name。それ以外の場合 (つまり、bulk_referenceが null またはゼロ以下の場合、行の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

「fo」ではなく「fi」として返される行 id=4 から product_name を取得するには...

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 に答える