简体   繁体   中英

Insert distinct values only for one column

Say, I have a table with five columns col1 , col2 , col3 , col4 and user_id . Now, I have an array of user_id values, say a thousand. I want to insert thousand of records where only distinct column value is user_id . If there is a simplier way rather than make a thousand of ('col1value','col2value','col3value','col4value',someUserId) and concatenate them in single insert into tbl (col1,col2,col3,col4,user_id) values query?

Update: I guess it needs some clarification

So here's simple example. Let's say I have an events table with fields event and user_id . Some call event occurs for users with id 1, 2, 5, 101, 233, 422 and 1000. So I need to insert 7 records into table so it should look like

+-------+---------+
| event | user_id |
|-------|---------|
|  call |       1 |
|  call |       2 |
|  call |       5 |
|  call |     101 |
|  call |     233 |
|  call |     422 |
|  call |    1000 |
+-------+---------+

I want to do it as efficiently database-wise as possible. So far, I think I have to make such SQL query:

insert into events (event,user_id) values ('call',1),('call',2),('call',5),('call',101),('call',233),('call',422),('call',1000);

then perform a single query

But maybe there is some more simple and efficient way? Maybe something with SQL parameters or such?

I understand your question that you have a high number of different user_id values that you want to insert, but for each new record you want the same values for col1 , col2 , col3 and col4 .

The easiest way to achieve this would be to set a DEFAULT value for each of the columns:

ALTER TABLE mytable CHANGE `col1` `col1` INTEGER NOT NULL DEFAULT 1234

This sets the default value for col1 to 1234 . I assumed the column to be of data type INTEGER , you need to change it accordingly.

If changing the table is not an option for you, then you could still build an insert statement that would insert all records in a single transaction:

$user_ids = array(5,6, 7, 8, 9, 10); // these are the user ids you want to insert
$default_vals = array(1, 2, 3, 4); // These are the default values used for col1, col2, col3 and col4

$con = new mysqli('mydomain', 'myuser', 'mypw', 'mydb');

$rows = array();
foreach ($user_ids as $id)
    $rows[] = "(".implode(',', $default_vals).",$id)";
$sql = "INSERT INTO mytbl (col1, col2, col3, col4, id) VALUES " . implode(',', $rows) . ";";

$con->query($sql);

Or, if for academic reason you'd rather write a single INSERT statement to do the whole job, you could write:

INSERT INTO mytbl (col1, col2, col3, col4, id)
SELECT * FROM 
  (SELECT 1, 2, 3, 4) AS DEFAULT_VALS,
  (SELECT 5
   UNION SELECT 6
   UNION SELECT 7
   UNION SELECT 8
   UNION SELECT 9) AS USER_IDS

However, the last approach really isn't very nice. Neither in terms of readability nor of performance.


Edit
I made a quick benchmark for you:

  • Inserting 10k different records like in my PHP sample took 1.5086660385132 seconds on my webserver.
  • The SELECT INTO approach with 10k UNION s took 3.3481941223145 seconds .

Easy choice, though.

Use :

INSERT INTO tbl (col1,col2,col3,col4,user_id)
VALUES 
  (1,2,3,4,1000),
  (2,3,4,5,1000),
  (6,7,8,9,1000),
  (1,2,3,4,1234),
  (4,3,2,1,1235);

Create unique index on user_id field. use INSERT IGNORE or INSERT ... ON DUPLICATE KEY UPDATE for ignoring duplicate insertion of user_id .

For details, kindly refer MySQL documentation.

http://dev.mysql.com/doc/refman/5.6/en/insert.html

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