1

したがって、たとえば、次の内容の「physical_address」フィールドのように、別のフィールドに分割する必要があるアドレス TEXT フィールドがあります。

| physical_address |
+------------------+
| 123 Street Name  |
| Suburb           |
| City             |
+------------------+

次のようになります。

| physical_address_1 | physical_address_2 | physical_address_3 |
+--------------------+--------------------+--------------------+
| 123 Street Name    | Suburb             | City               |
+--------------------+--------------------+--------------------+

上記の形式でアプリにインポートする必要があるため、これは一時的なものです。そのため、select ステートメントが最適なオプションになりますが、それほど単純ではないと思います。

この種の作品は、完全ではありません:

SELECT
physical_address,
SUBSTRING_INDEX(physical_address, CHAR(10), -5) AS a,
SUBSTRING_INDEX(physical_address, CHAR(10), -4) AS b,
SUBSTRING_INDEX(physical_address, CHAR(10), -3) AS c,
SUBSTRING_INDEX(physical_address, CHAR(10), -2) AS d,
SUBSTRING_INDEX(physical_address, CHAR(10), -1) AS e
FROM clients LIMIT 5

5 行の TEXT 値を使用すると、それ以下でも完全に機能し、最初のいくつかのフィールド (行によって異なります) が値を繰り返すことがわかります。この cos の SQL Fiddle をセットアップできません。リターン フィードをクリーンアップしているように見えるため、スキーマの例を次に示します。

CREATE TABLE clients (id int unsigned auto_increment primary key, physical_address text);

INSERT INTO clients (id,physical_address) VALUES (1,"123 Street,\r\n123 Suburb,\r\n123 City");
INSERT INTO clients (id,physical_address) VALUES (2,"456 Street,\r\n456 Suburb,\r\n456 City,\r\n456 Province");
INSERT INTO clients (id,physical_address) VALUES (3,"789 Street,\r\n789 Suburb,\r\n789 City,\r\n789 Province,\r\n789 Country");
4

2 に答える 2

1

各アドレスを特定のユーザーなどに識別する何らかの方法があると仮定します。その場合、ユーザー定義変数を使用して行番号を割り当て、集計関数と式を使用してデータをピボットできます。CASE

select id,
  max(case when rn=1 then physical_address end) Physical_address1,
  max(case when rn=2 then physical_address end) Physical_address2,
  max(case when rn=3 then physical_address end) Physical_address3
from
(
  select t.physical_address,
    id,
    @row:=case when @prev=id then @row else 0 end +1 rn,
    @prev:=id
  from yourtable t
  cross join (select @row:=0, @prev:=0)r
  order by t.id
) src
group by id
order by id

SQL Fiddle with Demoを参照してください。

住所データが単一の行にある場合は、最初にデータを複数の行に分割する必要があります。次に、列に回転できます。

データを分割するために使用される関数とプロシージャを作成しました。@Johan の回答 hereに基づいてコードを作成しました。

まず、clientsテーブルの代替バージョンを作成しました。

CREATE TABLE clients_new
    (id int,`physical_address` varchar(256))
;

次に、関数/手順を作成しました。

CREATE FUNCTION strSplit(x VARCHAR(5000), delim VARCHAR(12), pos INTEGER) 
RETURNS VARCHAR(256)
BEGIN
  DECLARE output VARCHAR(256);
  SET output = REPLACE(SUBSTRING(SUBSTRING_INDEX(x, delim, pos)
                 , LENGTH(SUBSTRING_INDEX(x, delim, pos - 1)) + 1)
                 , delim
                 , '');
  IF output = '' THEN SET output = null; END IF;
  RETURN output;
END //


CREATE PROCEDURE BadTableToGoodTable()
BEGIN
  DECLARE i INTEGER;

  SET i = 1;
  REPEAT
    INSERT INTO Clients_new (id, physical_address)
      SELECT id, strSplit(physical_address, '\r\n', i) 
      FROM Clients
      WHERE strSplit(physical_address, '\r\n', i) IS NOT NULL;
    SET i = i + 1;
    UNTIL ROW_COUNT() = 0
  END REPEAT;
END //

プロシージャを実行するには、次を使用します。

call BadTableToGoodTable;

データを分割する手順が完了したら、私が提供した元のクエリを使用して、必要に応じて新しいテーブルと追加の列を含めるためにいくつかの小さな編集を加えることができます。

select id,
  max(case when rn=1 then physical_address end) Physical_address1,
  max(case when rn=2 then physical_address end) Physical_address2,
  max(case when rn=3 then physical_address end) Physical_address3,
  max(case when rn=4 then physical_address end) Physical_address4,
  max(case when rn=5 then physical_address end) Physical_address5
from
(
  select t.physical_address,
    id,
    @row:=case when @prev=id then @row else 0 end +1 rn,
    @prev:=id
  from clients_new t
  cross join (select @row:=0, @prev:=0)r
  order by t.id
) src
group by id
order by id
于 2013-02-10T22:21:31.163 に答える
0

すべてを選択してから、php で expand("/n") を使用してスライスすることができます。次に、必要に応じてデータベースに保存します。mySQLレベルからそれを行うことはできません

于 2013-02-10T21:47:24.677 に答える