2

MySQL。2つの列、同じテーブル。
列1にはproduct_idがあります
列2にはcategory_idsがあります(場合によっては2つのカテゴリなので、23,43のようになります

)製品番号。

すなわち
表:

product_id | category_ids 
100        | 200,300
101        | 201

クエリ結果:テーブルを変更しようとしない

100 | 200
100 | 300
101 | 201


編集:(注)私は実際にはテーブルを操作したくありません。PHPでクエリを実行するだけなので、必要に応じてデータを使用できます。

4

1 に答える 1

1

データベーステーブルの実装は設計が悪いようですが、あなたの場合、必要なのはGROUP_CONCATの逆関数ですが、残念ながらMySQLには存在しません。

2つの実行可能な解決策があります:

  1. product_idデータの保存方法を変更します(フィールドに重複を許可し、product_id異なるレコードに同じレコードを複数配置しますcategory_id
  2. アプリケーション内からクエリ結果を操作します(質問でPHPについて言及しました)。この場合、category_ids列の値を分割し、独自の結果セットをアセンブルする必要があります。

(一時テーブルとストアドプロシージャを使用する)トリックのような3番目の解決策もあります。まず、このストアドプロシージャを宣言する必要があります。

DELIMITER $$
CREATE PROCEDURE csv_Explode( sSepar VARCHAR(255), saVal TEXT )
body:
BEGIN

  DROP TEMPORARY TABLE IF EXISTS csv_Explode;
  CREATE TEMPORARY TABLE lib_Explode(
    `pos` int unsigned NOT NULL auto_increment,
    `val` VARCHAR(255) NOT NULL,
    PRIMARY KEY  (`pos`)
  ) ENGINE=Memory COMMENT='Explode() results.';

  IF sSepar IS NULL OR saVal IS NULL THEN LEAVE body; END IF;

  SET @saTail = saVal;
  SET @iSeparLen = LENGTH( sSepar );

  create_layers:
  WHILE @saTail != '' DO

    # Get the next value
    SET @sHead = SUBSTRING_INDEX(@saTail, sSepar, 1);
    SET @saTail = SUBSTRING( @saTail, LENGTH(@sHead) + 1 + @iSeparLen );
    INSERT INTO lib_Explode SET val = @sHead;

  END WHILE;

END; $$
DELIMITER ;

次に、分解する列の配列を渡すプロシージャを呼び出す必要があります。

CALL csv_explode(',', (SELECT category_ids FROM products WHERE product_id = 100));

この後、次のように一時テーブルに結果を表示できます。

SELECT * FROM csv_explode;

そして、結果セットは次のようになります。

+-----+-----+
| pos | val |
+-----+-----+
|   1 | 200 |
|   2 | 300 |
+-----+-----+

それはあなたにとっての出発点かもしれません...

于 2012-06-19T12:25:23.013 に答える