15

I have a "tags" table, which has a UNIQUE on the "tags" column, to prevent duplicates.

I have a "bookmarks_tags" table, which relates bookmarks to tags, and it has a UNIQUE on the "bookmark_id" and "tag_id" columns, to prevent duplicates.

However, I need people to be able to add the same tag, and to accomplish this, I need some means of retrieving the ID of the existing tag to use as reference in the "bookmarks_tags" table.

Is there a way of writing an INSERT so that if it detects a duplicate, it returns the ID of that duplicate? Or, alternatively, would an INSERT ... SELECT be more appropriate for "bookmarks_tags" table?

The key thing here is that it has to work under both conditions; add as new, or retrieve old.

Also, LAST_INSERT_ID() is useless in this scenario, as the tag in question could have been added at any time.

Any ideas?

Ross Smith II
  • 11,799
  • 1
  • 38
  • 43
Wayne Smallman
  • 1,690
  • 11
  • 34
  • 56
  • [this](http://stackoverflow.com/questions/2594829/finding-duplicate-values-in-a-sql-table) will help you – matzone May 04 '13 at 13:32
  • I can write a SELECT query, but that isn't the problem. I need to know if an INSERT can accomplish the same thing, saving the extra coding; I'm using a framework, so there's several files that would need changing. – Wayne Smallman May 04 '13 at 13:36
  • Possible duplicate of [MySQL ON DUPLICATE KEY - last insert id?](https://stackoverflow.com/questions/778534/mysql-on-duplicate-key-last-insert-id) – Lorenz Meyer Jun 14 '17 at 08:54

2 Answers2

23
$query = "INSERT INTO table SET unique1=value1 AND unique2=value2… ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id)";
$insert_result = mysql_query($query);
$id = mysql_insert_id();
return $id;

Insert Into Database or Return ID of Duplicate Row in MySQL (Backup link @WebArchive)

Enissay
  • 4,969
  • 3
  • 29
  • 56
Pham Quang
  • 331
  • 1
  • 5
6

One way to do this is using INSERT IGNORE:

INSERT IGNORE INTO tags (tags,...) VALUES (the_new_tags, ...);

SELECT tag_id FROM tags WHERE tags=the_new_tags;
Ross Smith II
  • 11,799
  • 1
  • 38
  • 43
  • Okay, that's the way I'm going. It's the one with the least hassle. Ross, thanks. – Wayne Smallman May 04 '13 at 20:35
  • Wouldn't @Pham Duc Quang method be better? Only requires one query. – Chris Oct 29 '13 at 15:06
  • 1
    Yes, `INSERT INTO tags SET tags=the_new_tags ON DUPLICATE KEY UPDATE tag_id=LAST_INSERT_ID(tag_id)` should work better, but I haven't tested it. – Ross Smith II Nov 04 '13 at 17:55
  • `Insert IGNORE` is a *bad idea* since it will ignore all errors (type, length etc.), instead is `INSERT ON DUPLICATE KEY UPDATE key=key` but will correctly throw other errors. https://dev.mysql.com/doc/refman/8.0/en/insert-on-duplicate.html See other answer: https://stackoverflow.com/a/16796885/3343553 – EdL May 27 '20 at 13:12