根据列中的分组元素对项目进行编号

时间:2017-07-21 08:43:37

标签: mysql

这是我的表:

Item1   | Item2     | Item3     | Element   | ItemNumber
==============================================================
rock    | n         | roll      | r         | 1
rock    | n         | roll      | o         | 0
rock    | n         | roll      | c         | 0
rock    | n         | roll      | k         | 1
rock    | n         | roll      | n         | 2
rock    | n         | roll      | r         | 3
rock    | n         | roll      | o         | 0
rock    | n         | roll      | l         | 0
rock    | n         | roll      | l         | 3
a       | tiny      | rock      | a         | 1
a       | tiny      | rock      | t         | 2
a       | tiny      | rock      | i         | 0
a       | tiny      | rock      | n         | 0
a       | tiny      | rock      | y         | 2
a       | tiny      | rock      | r         | 3
a       | tiny      | rock      | o         | 0
a       | tiny      | rock      | c         | 0
a       | tiny      | rock      | k         | 3

我想根据ItemNumber列中的值更新列Element,使所有元素对应于它所属的项目编号。基本上,我只想将正确的缺失值添加到ItemNumber,其中当前值为0。我的表中有超过600.000行,元素数量不等。

决赛桌应如下所示:

Item1   | Item2     | Item3     | Element   | ItemNumber
==============================================================
rock    | n         | roll      | r         | 1
rock    | n         | roll      | o         | 1
rock    | n         | roll      | c         | 1
rock    | n         | roll      | k         | 1
rock    | n         | roll      | n         | 2
rock    | n         | roll      | r         | 3
rock    | n         | roll      | o         | 3
rock    | n         | roll      | l         | 3
rock    | n         | roll      | l         | 3
a       | tiny      | rock      | a         | 1
a       | tiny      | rock      | t         | 2
a       | tiny      | rock      | i         | 2
a       | tiny      | rock      | n         | 2
a       | tiny      | rock      | y         | 2
a       | tiny      | rock      | r         | 3
a       | tiny      | rock      | o         | 3
a       | tiny      | rock      | c         | 3
a       | tiny      | rock      | k         | 3

我如何使用MySQL做到这一点?

2 个答案:

答案 0 :(得分:1)

您需要的是一个唯一标识每一行的列。拥有这样一个列(a.k.a.主键)总是一个好主意。

另一个使用列是确定行的排序顺序的列。换句话说,当您选择包含r,o,c和k的行之后,应确定列中包含元素r,o,l和l的列。在一个可能的解决方案中,我为此使用了auto_increment列。

CREATE TABLE t
    (id int auto_increment primary key, `Item1` varchar(4), `Item2` varchar(4), `Item3` varchar(4), `Element` varchar(1), `ItemNumber` int)
;

INSERT INTO t
    (`Item1`, `Item2`, `Item3`, `Element`, `ItemNumber`)
VALUES
    ('rock', 'n', 'roll', 'r', 1),
    ('rock', 'n', 'roll', 'o', 0),
    ('rock', 'n', 'roll', 'c', 0),
    ('rock', 'n', 'roll', 'k', 1),
    ('rock', 'n', 'roll', 'n', 2),
    ('rock', 'n', 'roll', 'r', 3),
    ('rock', 'n', 'roll', 'o', 0),
    ('rock', 'n', 'roll', 'l', 0),
    ('rock', 'n', 'roll', 'l', 3),
    ('a', 'tiny', 'rock', 'a', 1),
    ('a', 'tiny', 'rock', 't', 2),
    ('a', 'tiny', 'rock', 'i', 0),
    ('a', 'tiny', 'rock', 'n', 0),
    ('a', 'tiny', 'rock', 'y', 2),
    ('a', 'tiny', 'rock', 'r', 3),
    ('a', 'tiny', 'rock', 'o', 0),
    ('a', 'tiny', 'rock', 'c', 0),
    ('a', 'tiny', 'rock', 'k', 3)
;

UPDATE t
JOIN (
  SELECT
  t.*
  , @v := IF(ItemNumber != 0, ItemNumber, @v) as new_itemnumber
  FROM
  t
  , (SELECT @v:=0) var_init_subquery
  ORDER BY id
  ) sq USING (id)
SET t.ItemNumber = sq.new_itemnumber;
  • 看到它在sqlfiddle here
  • 中正常工作

答案 1 :(得分:0)

每个短语(摇滚乐,一块小石头)的每个项目(1,2,3)都有这样的东西:

UPDATE table_name
SET ItemNumber = 1
WHERE ItemNumber = 0 AND Item1 LIKE CONCAT('%', Element, '%') AND Item1 = 'rock';

唯一的问题是Element ='r'和Element ='o'的元组,因为它们与'rock'和'roll'都匹配。这将是复杂的,因为元组应该是无序的,因此无法区分ItemNumber = 1和ItemNumber = 3.我建议重新设计你的表。