1

所以我有一个地址 TEXT 字段,我需要将其拆分为单独的字段,例如:“physical_address”字段,内容如下:

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

会成为:

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

现在这只是暂时的,因为我需要以上述格式将其导入应用程序,因此选择语句将是最佳选择 - 尽管我想它不会那么简单。

这种作品,但不完全是:

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 值,可以完美运行,少一点,您会看到前几个字段(取决于行)将重复值。无法为此设置 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 在此处的回答

首先,我创建了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.ini 中的 explode("/n") 对其进行切片。接下来根据需要将其保存到数据库中。它不可能从 mySQL 级别做到这一点

于 2013-02-10T21:47:24.677 回答