【问题标题】:How to create custom column with auto-increment characters如何使用自动递增字符创建自定义列
【发布时间】:2016-03-23 15:29:09
【问题描述】:

我想将一个自定义列显示为别名,但需要使用自动字符递增。

id      subid   dollar  packetname
168     355     5813    ND-1
169     355     359     ND-1
170     356     559     ND-2
171     362     4536    ND-10
172     362     484     ND-10
134     329     4698    ND-12
135     329     435     ND-12
125     330     6293    ND-13
126     330     4293    ND-13
127     330     693     ND-13

我需要一个带有另一个更新数据包的输出。带有自动增量字符的列

id      subid   dollar  packetname      updated packet
168     355     5813    ND-1            ND-1
169     355     359     ND-1            ND-1A
170     356     559     ND-2            ND-2
171     362     4536    ND-10           ND-10
172     362     484     ND-10           ND-10A
134     329     4698    ND-12           ND-12
135     329     435     ND-12           ND-12A
125     330     6293    ND-13           ND-13
126     330     4293    ND-13           ND-13A
127     330     693     ND-13           ND-13B

【问题讨论】:

  • 嗯,假设第 37 列将是 ND-13Z,您希望第 38 列是什么?
  • @Timekiller 不,我对 38 日没有任何期待。我的最高要求是 A 到 G 而已。

标签: mysql auto-increment


【解决方案1】:

您可以使用此类查询来制作附加字段

SELECT concat(packetname, 
              elt(if(@t=packetname, @n:=@n+1, @n:=1),
                  '','A','B','C','D','E','F','G')) `updated packet`, 
       id, subid, dollar, @t:=packetname packetname
    FROM t
      cross join
         (SELECT @n:=1, @t:="") n
  order by packetname

demo on sqlfiddle

【讨论】:

    【解决方案2】:

    我认为你最好的选择是SELECT 退出当前的数据包表,并在此过程中对其进行修改,然后将INSERT 放入一个新表中。完成此操作后,您可以删除原始表,然后将新表重命名为旧表。

    INSERT INTO newpacket (id, subid, dollar, packetname, `updated packet`)
    SELECT p1.id, p1.subid, p1.dollar, p1.packetname, p2.`updated packet`
    FROM packet p1
    INNER JOIN
    (
        SELECT p.id, p.subid,
            CASE WHEN (SELECT p.id - MIN(t.id) FROM packet t WHERE t.subid = p.subid) > 0
            THEN CONCAT(packetname,
                        CHAR(((SELECT p.id - MIN(t.id) FROM packet t WHERE t.subid = p.subid) + 64) USING utf8))
            ELSE packetname END AS `updated packet`
        FROM packet p
    ) p2
    ON p1.subid = p2.subid AND p1.id = p2.id
    

    【讨论】:

    • id/subid 上操作是否安全?如果id 值在实际数据中是稀疏的怎么办?如果不同的subid 有相同的packetname 怎么办?
    • 我假设 id - subid 组合是独一无二的。我认为我们需要做出一些假设才能在这里猜测解决方案。顺便说一句,@Timekiller 是一个合适的名称。我已经在这个问题上花了一个小时。
    • 那么你得到了什么错误? SQLFiddle 已经关闭了一段时间。
    • 我在ON 子句中遗漏了一个条件。你能再试一次吗?
    【解决方案3】:

    您可以创建触发器。

    create trigger my_trigger before insert on mytable for each row 
    begin
    DECLARE samecount INT;
      set samecount = ( select count(*) from mytable where packetname = new.packetname );
      if samecount = 0 then
        set new.updated_packet = new.packetname;
      else
        set new.updated_packet = concat(new.packetname,conv(samecount+9,10,36));
      end if;
    end;
    

    在插入新行之前,它会计算存在多少具有相同packetname 的行。当有一个或多个时,count+9 转换为基数 36 - 除了一直到 Z 之外,它几乎与 HEX 相同。因此,如果 count 为 1,它变为1+9=10=A。结果值与packetname 连接。 如果相同的行超过 37,它不会失败,但会追加 10 代替 38。

    请记住,这不完全是 auto increment,它可能会受到竞争条件的影响,当两个用户在完全相同的时间插入相同的 packetname 时,计数查询可以为两者返回相同的值。

    编辑: 请注意,此解决方案适用于您之后需要将 new 行插入该表并希望它们自动填充 updated_packet 的情况。如果您还想更新现有行,一种方法是创建一个具有相同结构的新表,在新表上创建该触发器,然后执行

    insert into newtable(id, subid, dollar, packetname)
    select id, subid, dollar, packetname from oldtable
    

    【讨论】:

      猜你喜欢
      • 2016-03-07
      • 1970-01-01
      • 2015-03-06
      • 2013-01-04
      • 1970-01-01
      • 2013-03-01
      • 2019-02-10
      • 1970-01-01
      相关资源
      最近更新 更多