2

id自動インクリメントキーを備えたテーブルがあり、同じitem_noidを共有してrefいるが異なるright/left(ただし、技術的item_noにはテーブル全体で複数回繰り返すことができますが、それはそうではありません)問題)、description連続する行では同じである場合もありますが、異なる場合もあります。

id | item_no | description | right\left | ref
1  | 1       | a1          | right      | aaa
2  | 1       | a1          | left       | aaa
3  | 2       | b1          | right      | bbb
4  | 3       | c1          | right      | ccc
5  | 3       | c2          | left       | ccc
6  | 4       | d1          | right      | ddd
7  | 4       | d1          | left       | ddd

私の問題は、「一致する」行のが異なるitem_no場合、その値に-rまたは-lを追加する必要があることです。description

したがって、私が探している結果は次のとおりです。

id | item_no | description | right\left | ref
1  | 1       | a1          | right      | aaa
2  | 1       | a1          | left       | aaa
3  | 2       | b1          | right      | bbb
4  | 3-r     | c1          | right      | ccc
5  | 3-l     | c2          | left       | ccc
6  | 4       | d1          | right      | ddd
7  | 4       | d1          | left       | ddd

テーブルをcsvにエクスポートしていますが、phpをあまり使用しておらず、mysqlステートメントだけを使用して結果をループアウトしています。これは、mysqlステートメント内で可能ですか、それともphpループに依存する必要がありますか?

4

4 に答える 4

2

私はこれを使用します:

update
  items inner join
  (select item_no from items
   group by item_no
   having count(distinct description)>1) dup
  on items.item_no=dup.item_no
set
  items.item_no=concat(items.item_no, '-', substr(rightleft, 1,1))

行が常に連続している場合は、次を使用することもできます。

update
  items i1 inner join items i2
  on (i1.id=i2.id+1 or i1.id=i2.id-1) 
     and (i1.item_no=i2.item_no)
     and (i1.description<>i2.description)
set i1.item_no=concat(i1.item_no, '-', substr(i1.rightleft, 1,1))

編集:行が常に連続していて、更新ではなく選択だけが必要な場合は、次を使用できます:

select
  i1.id,
  case when i1.description=i2.description or i2.id is null then i1.item_no else
            concat(i1.item_no, '-', substr(i1.rightleft, 1,1)) end,
  i1.description, i1.rightleft, i1.ref
from
  items i1 left join items i2
  on (i1.id=i2.id+1 or i1.id=i2.id-1) and (i1.item_no=i2.item_no)
order by i1.id
于 2012-12-11T14:44:06.903 に答える
1

mysqlを使用している場合は、PHPループに依存します。OracleまたはSQLサーバーを使用している場合は、ストアドプロシージャをプログラムできます。

スクリプトは次のようになります。

$dbh = new PDO('mysql:host='.DATABASE_HOST.';dbname='.DATABASE_NAME, DATABASE_USER, DATABASE_PASSWORD);
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

$data = $dbh->query("SELECT * FROM ExampleTable");
$dbh->beginTransaction();

foreach($data as $row)
{
    $append = $row["right\left"] == "left" ? $row["item_no"]."-l" : $row["item_no"]."-r";
    $stmnt = $dbh->prepare("UPDATE ExampleTable SET item_no = :item WHERE id = :id");
    $stmnt->execute(array(":item" => $append,":id" => $row["id"]));
}

// Do some exception handling if something goes wrong you can allways do a rollback
// With PDO $dbh->rollBack();
$dbh->commit();
$dbh = null;
于 2012-12-11T14:42:57.890 に答える
1

これを試して:

SELECT 
  id, 
  CASE RightLeft
    WHEN  'right' THEN CONCAT(item_no, '-r' )
    WHEN  'left'  THEN CONCAT(item_no, '-l' )
  END AS item_no,
  DESCRIPTION,
  Rightleft,
  ref
FROM Items
WHERE item_no IN
(
  SELECT i1.item_no
  FROM items i1
  GROUP BY i1.item_no
  HAVING(COUNT(DISTINCT description)) > 1);

SQLフィドルデモ

これはあなたに与えるでしょう:

| ID | ITEM_NO | DESCRIPTION | RIGHTLEFT | REF |
------------------------------------------------
|  4 |     3-r |          c1 |     right | ccc |
|  5 |     3-l |          c2 |      left | ccc |
于 2012-12-11T14:48:14.077 に答える
0

このようなもの

UPDATE [dbo].[maTable] SET [item_no] = [item_no]+'r' WHERE not distinct [description] from [dbo].[maTable]

[description]が同一でない登録行に「r」を追加する必要があります(SQL Server用にコード化されています)

于 2012-12-11T14:46:05.480 に答える