我有一个mysql表,其中有一列例如叫名字。列数据具有特定模式nameBase + number。 E.g。
name
----------
test0
test1
test2
stack0
stack1
stack2
每次我想要向列中添加数据时,我必须找到特定nambeBase的最后一个数字,并添加新条目+数字+ 1.
例如,如果现在测试了,我必须将test3添加到db。
我的问题:1.检查nameBase是否已经存在于db(sth like contains)和2.find last nameBase数字的最佳方法是什么。例如。这里的测试是3.
更新:每个人,一次更新。我终于使用了java Pattern类。这么酷又容易。它使一切变得如此简单。我只是可以添加/ d到模式,然后我可以检查是否匹配名称,并可以使用模式组轻松访问第二部分。
答案 0 :(得分: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
可能匹配)但更昂贵:< / p>
SELECT
MAX(REPLACE(name, <the name to search>, '')) AS maxnum
FROM tbl
WHERE
name REGEXP '^<the name to search>[0-9]+$'
答案 1 :(得分:1)
我会使用带有两列的附加表来执行此操作,并在此表中存储每个名称和最后分配的ID。然后替换原始表中的nameBase+number
列,其中name
列是添加表的外键,number
列是该条目的适当计数。
操作起来会更容易,也更有效率。
答案 2 :(得分: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";
答案 3 :(得分: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 ......)不同。
如果可以的话,我会遵循建议多个列或表的其他人的建议。我只提供这种方法,您无需修改当前表。
答案 4 :(得分: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;
这个想法是:
我没有测试过这个...我希望它能引导你朝着正确的方向前进。
请注意,我使用常量字符串“stack”作为示例,您可能希望使其动态化。