简体   繁体   中英

INSERT statement SELECT CONCAT

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:

  1. 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%' 
  2. 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM