MySQL Insert 功能类似于 Window 的默认文件命名

Posted

技术标签:

【中文标题】MySQL Insert 功能类似于 Window 的默认文件命名【英文标题】:MySQL Insert with functionality similar to Window's default file naming 【发布时间】:2016-06-11 12:03:22 【问题描述】:

我有一个带有名称列的表。最初没有将名称添加到表中,但我想在插入新行时添加默认名称,就像创建新文件时窗口的功能一样。我试图弄清楚如何查询序列中的下一个数字。

例如,如果我的表格如下所示:

id | name
==========
1  | New Name (1)
2  | real name
3  | New Name

下一个插入行的名称应该是“新名称 (2)”。如果我的表是这样的:

id | name
==========
1  | New Name (2)
2  | real name

或者这个:

id | name
==========
1  | another name
2  | real name

下一个插入行的名称应该是“新名称”。如果我的表是这样的:

id | name
==========
1  | New Name (2)
2  | real name
3  | New Name
4  | New Name (3)

下一个插入行的名称应该是“新名称 (1)”。到目前为止,我能够创建查询以获取现有数字(“新名称”= 0)

    SELECT SUBSTRING_INDEX(SUBSTR(d.name,INSTR(d.name,'(') + 1), ')', 1)
    FROM data d
    WHERE d.widget_name REGEXP '^New[[:space:]]Name[[:space:]]\\([[:digit:]]\\)$'
    UNION 
    SELECT 0 
    FROM data d
    WHERE d.name REGEXP '^New[[:space:]]Name$' 

现在我需要一种方法将该数字列表转换为单个数字,该数字将指示下一个默认名称枚举是什么。我试过使用NOT EXISTSfrom this question,但我不知道如何在FROMWHERE中使用上面的代码。

我还尝试通过使用a_horse_with_no_name's answer in this question 创建 row_num 功能来做到这一点。假设 num_data 是查询的结果(试图保持它干净)表,它的列名是 name_num:

  SELECT IFNULL(row_number, (SELECT IFNULL(MAX(name_num),0)
                             FROM num_data))
  FROM (SELECT @rownum:=@rownum + 1 AS row_number,  t.*
        FROM (num_data) t,
        (SELECT @rownum := 0) r) gap_table
  WHERE gap_table.row_number <> gap_table.widget_num
  ORDER by row_number
  LIMIT 1;

但这似乎也不对。

【问题讨论】:

【参考方案1】:

如果您想要给定名称的下一个名称,我希望查询看起来像这样:

select (case when count(*) = 0 then $name
             else concat($name, '(',
                         max(substring_index(name, ' (', -1) + 0) + 1,
                         ')')
        end)
from num_data
where name rlike concat($name, ' [(][0-9]+[)]' or
      name = $name;

Here 是一个演示它的 SQL Fiddle。

这假定正在测试的名称由名为 $name 的参数提供。

注意:以上查询生成新名称。如何依次获取下一个数字应该很明显了。

【讨论】:

嗯,好像少了点什么,我尝试过使用查询,where 子句不起作用,所以我改用我的。它缺少一个案例,当您没有可以通过添加此 when max(name REGEXP $name = 0) then $name 修复的数字的 $name 时会发生什么。但由于max,查询似乎没有填补空白。 @GorodonLinoff 几乎,它没有填补空白,也没有处理没有 $name 而已经有 $name(1) 的情况等等。我修改了您的查询以支持它。【参考方案2】:

感谢@GorodonLinoff 的回答,这成功了:

select (case when count(*) = 0 then '$name'
             when max(name = '$name') = 0 then '$name'
             when max(name = '$name(1)') = 0 then '$name(1)'
             else concat('$name', '(', max(substring_index(name, '(', -1) + 0) + 1, ')')
        end)
from data
where name rlike concat('$name', '[(][0-9]+[)]') or
      name = '$name';

【讨论】:

以上是关于MySQL Insert 功能类似于 Window 的默认文件命名的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 2008 中的功能类似于 mysql 中的 GREATEST?

Mysql数据闪回的奇技淫巧(binlog2sql)

类似于 MySQL FIELD() 函数的 MS SQL Server 功能是啥?

SQL Server 是不是提供类似于 MySQL 的 ON DUPLICATE KEY UPDATE 的功能

mysql 创建[序列],功能类似于oracle的序列

mysql 创建[序列],功能类似于oracle的序列