Solomon
Solomon

Reputation: 189

Using SQL Sub-queries in an INSERT Statement

Here are the two tables created:

CREATE TABLE category_tbl(
id int NOT NULL AUTO_INCREMENT,
name varchar(255) NOT NULL,
subcategory varchar(255) NOT NULL,
PRIMARY KEY(id),
CONSTRAINT nameSubcategory UNIQUE KEY(name, subcategory)
) ENGINE=InnoDB;

CREATE TABLE device(
id INT NOT NULL AUTO_INCREMENT,
cid INT DEFAULT NULL,
name VARCHAR(255) NOT NULL,
received DATE,
isbroken BOOLEAN,
PRIMARY KEY(id),
FOREIGN KEY(cid) REFERENCES category_tbl(id)
) ENGINE=InnoDB;

Below is the instruction that was given to me:

-- insert the following devices instances into the device table (you should use a subquery to set up foriegn keys referecnes, no hard coded numbers):
-- cid - reference to name: phone subcategory: maybe a tablet?
-- name - Samsung Atlas
-- received - 1/2/1970
-- isbroken - True

I'm getting errors on the insert statement below from attempting to use a sub-query within an insert statement. How would you solve this issue?

INSERT INTO devices(cid, name, received, isbroken)
VALUES((SELECT id FROM category_tbl WHERE subcategory = 'tablet')  , 'Samsung Atlas', 1/2/1970, 'True');

Upvotes: 0

Views: 2412

Answers (2)

Alex
Alex

Reputation: 17289

  1. You have different table name in CREATE TABLE and INSERT INTO so just choose one device or devices

  2. When insert date format use the good one like DATE('1970-02-01')

  3. When insert boolean - just TRUE with no qoutes I beleive.

http://sqlfiddle.com/#!9/b7180/1

INSERT INTO devices(cid, name, received, isbroken)
VALUES((SELECT id FROM category_tbl WHERE subcategory = 'tablet')  , 'Samsung Atlas', DATE('1970-02-01'), TRUE);

Upvotes: 1

spencer7593
spencer7593

Reputation: 108380

It's not possible to use a SELECT in an INSERT ... VALUES ... statement. The key here is the VALUES keyword. (EDIT: It is actually possible, my bad.)

If you remove the VALUES keyword, you can use the INSERT ... SELECT ... form of the INSERT statement statement.

For example:

INSERT INTO mytable ( a, b, c) SELECT 'a','b','c'

In your case, you could run a query that returns the needed value of the foreign key column, e.g.

SELECT c.id
  FROM category_tbl c
 WHERE c.name = 'tablet'
 ORDER BY c.id
 LIMIT 1

If we add some literals in the SELECT list, like this...

SELECT c.id              AS `cid`
     , 'Samsung Atlas'   AS `name`
     , '1970-01-02'      AS `received`
     , 'True'            AS `isBroken`
  FROM category_tbl c
 WHERE c.name = 'tablet'
 ORDER BY c.id
 LIMIT 1

That will return a "row" that we could insert. Just precede the SELECT with

INSERT INTO device (`cid`, `name`, `received`, `isbroken`)

NOTE: The expressions returned by the SELECT are "lined up" with the columns in the column list by position, not by name. The aliases assigned to the expressions in the SELECT list are arbitrary, they are basically ignored. They could be omitted, but I think having the aliases assigned makes it easier to understand when we run just the SELECT portion.

Upvotes: 0

Related Questions