简体   繁体   中英

SQL Statement to INSERT into one table from two (using id from another w/no join criteria)

I have two tables:

CREATE TABLE `data_items` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `data` longtext NOT NULL,
  `created` datetime NOT NULL,
  `updated` datetime NOT NULL,
  `data_item_type` varchar(255) NOT NULL,
  `data_source_id` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `IDX_AFA125D21A935C57` (`data_source_id`),
  CONSTRAINT `FK_AFA125D21A935C57` FOREIGN KEY (`data_source_id`) REFERENCES `data_sources` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7192 DEFAULT CHARSET=utf8;

AND

CREATE TABLE `map_locations` (
  `id` int(11) NOT NULL,
  `latitude` decimal(9,6) DEFAULT NULL,
  `longitude` decimal(9,6) DEFAULT NULL,
  `name` varchar(255) DEFAULT NULL,
  `address` varchar(255) DEFAULT NULL,
  `status` varchar(255) NOT NULL,
  `message_codes` longtext NOT NULL,
  PRIMARY KEY (`id`),
  CONSTRAINT `FK_B28E0DE7BF396750` FOREIGN KEY (`id`) REFERENCES `data_items` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

I'm trying to accomplish a two-step process. The first query works fine:

INSERT INTO data_items (`data`, created, updated, data_item_type, data_source_id) SELECT data_items.data, now(), now(), data_items.data_item_type, 2
    FROM data_items
    WHERE data_items.data_source_id = 1

--> 1 and 2 are example values

Now, I want to take every id from 'data_items' (the auto-incs that just got created) and use those id's when inserting each new (corresponding row) in the 'map_locations' table.

So,

data_items
id | data_source_id
1 | 1
2 | 1
3 | 2
4 | 2

map_locations
id | content
1 | aaa
2 | bbb
.... 
3 | aaa
4 | bbb

I need to copy row (1, 2), use the id from data_items (3,4) and insert those rows.

Hope this makes sense..it's rather confusing. TIA.

  1. You need the newly created data_items to reference their original counterparts; the easiest way to do this would be to modify the schema so that the table includes a self-referencing foreign key:

     ALTER TABLE data_items ADD COLUMN underlying_id INT(11) NULL, ADD FOREIGN KEY (underlying_id) REFERENCES data_items (id) 
  2. The insertion into data_items then becomes:

     INSERT INTO data_items (underlying_id, data, created, updated, data_item_type, data_source_id) SELECT id, data, NOW(), NOW(), data_item_type, 2 FROM data_items WHERE data_source_id = 1 
  3. One can now perform a self-join to obtain the newly created id s:

     INSERT INTO map_locations (id, content) SELECT new.id, map_locations.content FROM map_locations JOIN data_items old USING (id) JOIN data_items new ON new.underlying_id = old.id WHERE old.data_source_id = 1 

    Ensure that you perform this query within the same transaction as the previous insertion, using the (default) REPEATABLE READ transaction isolation level, to ensure that any concurrent changes to the data_items table don't lead to inconsistent state.

  4. Again, within the same transaction, clear the underlying_id reference:

     UPDATE data_items SET underlying_id = NULL 

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