Table should looks like this:
idname a c name
1 b d elisa1
2 b d elisa2
3 b d elisa3
And next elisa will be elisa4
And the INSERT statement:
INSERT INTO patients
SET a=b, c=d (name)
SELECT CONCAT('elisa', CASE WHEN COUNT(idname) = 0 THEN '' ELSE COUNT(idname) END),
FROM patients WHERE name LIKE 'elisa%
INSERT statement won't add any records at all.
Some arrogant dude will insist you need to use a database sequence but depending upon what you are trying to accomplish, something like will work with Oracle:
INSERT INTO patients VALUES(
(SELECT COUNT(*) FROM patients WHERE name LIKE 'elisa%'),
'b','d',
(SELECT CONCAT('elisa', CASE WHEN COUNT(idname) THEN 0 ELSE COUNT(idname) END) FROM patients WHERE name LIKE 'elisa%'));
Alternatively, if you may have gaps in the numbers and having unique, increasing numbers matters, something like this might prove more satisfactory:
INSERT INTO patients VALUES(
(SELECT NVL(MAX(idname),0)+1 FROM patients WHERE name LIKE 'elisa%'),
'b','d',
CONCAT('elisa', (SELECT NVL(MAX(idname),0)+1 FROM patients WHERE name LIKE 'elisa%')));
Please keep in mind that these won't work correctly if you have multiple transactions going on at the same time. For that, you will need a database sequence but then you will have one set of numbers for all names, so elisa5 will be followed by bob6 and joe7.
A database sequence version:
INSERT INTO patients VALUES(
patient_name_seq.currval,
'b','d',
CONCAT('elisa',patient_name_seq.nextval));
there are two issues:
SET
is used in updates, not inserts. The query should have the form
INSERT INTO patients (a, c, "name") SELECT 'b' , 'd' , CONCAT('elisa', CASE WHEN COUNT(idname) = 0 THEN '' ELSE COUNT(idname) END) FROM patients WHERE name LIKE 'elisa%'
CONCAT('elisa', CASE WHEN COUNT(idname) = 0 THEN '' ELSE COUNT(idname) END)
will result in a lag between the value idname
& the suffix after name
, ie in the row where idname
= 2
, name
= elisa1
. This differs from what is stated as desired in the question.
To change that, we can write
CONCAT('elisa', COUNT(idname)+1)
You can do this
INSERT INTO patients (a, c, name)
SELECT 'b', 'd', CONCAT('elisa', COALESCE((
SELECT SUBSTRING(MAX(name), CHAR_LENGTH('elisa') + 1) + 1
FROM patients
WHERE name LIKE 'elisa%'
), ''));
FYI: Such query is a subject for race conditions and does't guarantee uniqueness of the generated name
value. Two or more connections may simultaneously obtain the same value. Therefore you'd need to take care of those situations in your client code, ie catching a unique constraint violation exception and retrying this query for a few times until you get successful outcome.
Here is a dbfiddle demo
Result:
+--------+------+------+--------+ | idname | a | c | name | +--------+------+------+--------+ | 1 | b | d | elisa1 | | 2 | b | d | elisa2 | | 3 | b | d | elisa3 | | 4 | b | d | elisa4 | +--------+------+------+--------+
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.