0

我有一个 mysql 表,其中有一列,例如名为 name。列数据具有特定的模式 nameBase+number。例如

name
----------
test0
test1
test2
stack0
stack1
stack2

每次我想向列中添加数据时,我都必须找到特定 nambeBase 的最后一个数字并添加新条目 +number+1。

例如,如果现在测试来了,我必须将 test3 添加到 db。

我的问题: 1. 检查 nameBase 是否已经存在于 db(sth like contains) 和 2.find 姓氏的最佳方法是什么。例如这里的测试是3。

更新:每个人,一个更新。我终于使用了 java Pattern 类。很酷很容易。它让一切变得如此简单。我只需将 /d 添加到模式,然后我可以检查它是否与名称匹配,并可以使用模式组轻松访问第二部分。

4

5 回答 5

3

这里真正的解决方案是更改数据库模式,将其分成列,名称和编号。然后通过以下方式获取聚合变得MAX()微不足道

SELECT name, MAX(num) AS num FROM tbl GROUP BY name

但是,如果更改它不是一个选项,我建议使用从列值REPLACE()删除MAX()名称部分,在查询时只留下数字部分,并获取它的聚合以找到它的最高现有数字:

SELECT
  MAX(REPLACE(name, <the name to search>, '')) AS maxnum
FROM tbl
WHERE 
  name LIKE '<the name to search>%'

或者代替LIKE,使用正则表达式,这比LIKE(如果名称包含另一个名称,LIKE可能匹配)更准确但更昂贵:

SELECT
  MAX(REPLACE(name, <the name to search>, '')) AS maxnum
FROM tbl
WHERE 
  name REGEXP '^<the name to search>[0-9]+$'
于 2012-07-07T20:45:35.373 回答
1

如果您无法更改架构,请尝试以下操作:

INSERT INTO names (name)
  SELECT CONCAT("stack", CAST(TRIM(LEADING "stack" FROM name) AS INT)+1) 
   WHERE name LIKE "stack%" ORDER BY name DESC LIMIT 1;

这个想法是:

  1. 选择“最高”的先前值,
  2. 名字的印章,
  3. 将剩余的字符串转换为 int,
  4. 添加一个,
  5. 然后把名字放回去。

我还没有测试过这个......我希望它能引导你朝着正确的方向前进。

请注意,我使用了一个常量字符串“stack”作为示例,您可能希望使其动态化。

于 2012-07-07T21:01:38.370 回答
1

假设您无法更改表的结构,您可以为所欲为。但是,它相当昂贵。

你想做的是这样的:

select name
from t
where left(name, length(<name parameter>)) = <name parameter>
order by name desc
limit 1

不幸的是,您的命名可能不允许这样做,因为您没有用零填充数字部分。

因此,以下解决了这个问题:

select name,
       cast(substring(name, length(<name parameter>), 1000) as int) as number
from t
where left(name, length(<name parameter>)) = <name parameter>
order by 2 desc
limit 1

这不是特别有效。此外,索引并不能真正帮助解决这个问题,因为字符串的整理顺序与数字的不同(test0、test1、test10、test100、test11 等与 0、1、2、3、4 ......)。

如果可以的话,我会听从建议多个列或表的其他人的建议。我只提供这种方法,您不必修改当前表。

于 2012-07-07T20:57:49.080 回答
1

如果可能的话,我会重组表格以将它们放置在 2 个表格(更好)或至少两列(中等)中。您拥有的结构根本没有标准化:-/

在不了解您的架构的情况下;这是我对两表解决方案的建议:(注意:这是标准化的,也遵循成语“不要存储可以计算的内容”)

names
------
id  | name
01  | test
02  | stack

name_hits
-------
name_id | date
01      | 01/01/2001
01      | 01/15/2001
01      | 04/03/2001
02      | 01/01/2001
...

然后像这样选择:

SELECT names.name, count(name_hits.id) as hits 
FROM names JOIN name_hits ON names.id=name_hits.name_id
GROUP BY names.id

并像这样插入:

INSERT INTO name_hits SELECT id, NOW() FROM names WHERE name = "stack";
于 2012-07-07T20:47:39.220 回答
1

我将使用带有两列的附加表来执行此操作,并将每个名称和最后分配的 ID 存储在该表中。然后将nameBase+number原始表中的name列替换为作为加法表的外键的number列,以及作为该条目的适当计数的列。

这将更容易和更有效地操作。

于 2012-07-07T20:45:30.907 回答