mysql - call to insert into another table on every value of select - mysql

I'm currently migrating data from our old database schema into a new one.
I have a table called Product on my old database, on my new database schema I still have a Product table and a new column for b_id, and another table B.
During migration, I will need to insert an entry to table B for every product that I have in my table and update the Product table to set the b_id for the newly created entry on b for this product. How can I accomplish this?
To transfer the data for the product table, I have:
INSERT INTO newSchema.Product
SELECT id, prodName
FROM oldSchema.Product
I'm thinking of looping into the oldSchema.Product and for every product, have a call to INSERT INTO B and UPDATE TABLE Product, but no idea how to put this into code.
Any help will be appreciated. Thanks!

The same goes for B table...
INSERT INTO newschema.B (product_id)
SELECT id
FROM oldschema.product
Edited:
CREATE TABLE newschema.b (
id INT NOT NULL AUTO_INCREMENT,
product_id INT,
PRIMARY KEY (id)
);
CREATE TABLE newschema.product (
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(35) NOT NULL,
b_id INT,
PRIMARY KEY (id),
FOREIGN KEY (b_id) REFERENCES b(id)
);
INSERT INTO newschema.b (product_id)
SELECT product_id
FROM oldschema.product ;
INSERT INTO newschema.product (id, name, b_id)
SELECT OP.id,
OP.name,
NB.id
FROM oldschema.product AS OP,
newschema.b AS NB
WHERE NB.product_id = OP.id ;

Related

MySQL: How do I get to a column of another table via a mapping table

I am trying to create a database for assignments where there is a table for the tasks, a table for the persons and a table for the assignment of a person to a task.
Now I have tried to access the task table with a select statement and at the same time get all assigned persons but nothing worked. (because a task is also assigned to other tables)
Is there a way or do I have to use several statements for this?
This is how i created my Tables:
CREATE TABLE Locations (ID INT AUTO_INCREMENT, LocationID VARCHAR(255),
PRIMARY KEY (ID));
CREATE TABLE Persons (ID INT AUTO_INCREMENT, FirstName VARCHAR(255), LastName
VARCHAR(255), PRIMARY KEY (ID));
CREATE TABLE Tasks (ID INT AUTO_INCREMENT , TaskName VARCHAR(255), LocationID
INT, PRIMARY KEY (ID),
FOREIGN KEY (LocationID) REFERENCES Locations(ID));
CREATE TABLE Assinment (TaskID INT, PersonID INT,
PRIMARY KEY (TaskID, PersonID), FOREIGN KEY (TaskID)
REFERENCES Tasks(ID), FOREIGN KEY (PersonID)
REFERENCES Persons(ID));
And this is the UML.
I do not want my joins on the Assinment table like
SELECT (FirstName, LastName, TaskName) FROM ((Assinment INNER JOIN Tasks ON
Assinment.TaskID = Tasks.ID) INNER JOIN Persons ON Assinment.PersonID =
Persons.ID)
because the tasks table has more joins (e.g. locations and priorities) so i want my query start with
SELECT (ID, TaskName, FirstName, LastName, LocationName) FROM Tasks [...]
so i can get all data by id of the task
The Output then should give me this table.
Thanks for help :)
EDIT
Ouput added and desired input is now more specified
You can try subqueries :
SELECT column-names
FROM table-name1
WHERE value IN (SELECT column-name
FROM table-name2
WHERE condition)

MySQL: how to insert into a table with two foreign keys linking to two other tables?

I have the following db structure with 3 tables as an example:
Employee
id // primary key, autoincrement
employee_no // a varchar
Scenario
id // primary key, autoincrement
key // a varchar
Case
id // primary key, auto-increment
employee_id // foreign key to Employee table
scenario_id // foreign key to Scenario table
Say I already have data in employee and scenario table and I want to insert a new case into the case table so that it fills the foreign keys during the insert. The new case has employee_no in employee table and key in scenario table. I will need to join the two tables using the above values to get employee id and scenario id.
This post (Mysql: How to insert values in a table which has a foreign key) showed how this can be done with one foreign key, how do I do the same thing with two foreign keys?
I currently have something like this that does not work:
INSERT INTO `case` (scenario_id, employee_id, employee_no)
SELECT
(SELECT scenario.id FROM scenario WHERE scenario.`key` = 'UC01') as scenario_id,
(SELECT employee.id, employee.employee_no FROM employee WHERE employee.employee_no = "0001") as employee_id, employee_no
Join the two tables:
INSERT INTO case (scenario_id, employee_id)
SELECT s.id, e.id
FROM scenario AS s
CROSS JOIN emplopyee AS e
WHERE s.`key` = 'UC01'
AND e.employee_no = '0001'

SQL issue with multiple foreign

Issue:
I'm using PostgreSQL Database.
I have one table (Albums) to be linked to two other tables (Clients, Domains). So if you are Client or Domain you can have Album. But in Albums table owner can handle only single foreign key. How can I solve this issue?
Dream: Single Album can own only (1) Client or Domain. Need fix issue with foreign keys. Albums: id | owner (multiple foreign -> Clients:id or Domains:id) --> can not do this | name. I just need some smart rework.
Tables (now can have Album only Domain):
Albums
Clients
Domains
Albums (table with foreign key yet):
id | owner (foreign key -> Domains:id) | name
Clients:
id | first_name | last_name
Domains:
id | owner | name
Add 2 FK columns, and a CHECK constraint, to enforce only one of them is NOT NULL...
Something like this:
CREATE TABLE albums (
id serial PRIMARY KEY,
client_id integer,
domain_id integer,
name varchar(255) NOT NULL,
FOREIGN KEY (client_id) REFERENCES clients(id),
FOREIGN KEY (domain_id) REFERENCES domains(id),
CHECK ((client_id IS NULL) <> (domain_id IS NULL))
);
To query you can use something like this:
SELECT a.id, COALESCE(c.id, d.id) AS owner_id, COALESCE(c.name, d.name) AS owner_name,
a.name AS title
FROM albums a
LEFT JOIN clients c ON a.client_id = c.id
LEFT JOIN domains d ON a.domain_id = d.id
#e_i_pi's version
CREATE TABLE entities (
id serial PRIMARY KEY,
type integer, -- could be any other type
-- any other "common" values
);
CREATE TABLE client_entities (
id integer PRIMARY KEY, -- at INSERT this comes from table `entities`
name varchar(255) NOT NULL,
);
CREATE TABLE domain_entities (
id integer PRIMARY KEY, -- at INSERT this comes from table `entities`
name varchar(255) NOT NULL,
);
CREATE TABLE albums (
id serial PRIMARY KEY,
owner_id integer FOREIGN KEY REFERENCES entities(id), -- maybe NOT NULL?
name varchar(255) NOT NULL,
);
Query:
SELECT a.id, owner_id, COALESCE(c.name, d.name) AS owner_name, a.name AS title
FROM albums a
LEFT JOIN entities e ON a.owner_id = e.id
LEFT JOIN client_entities c ON e.id = c.id AND e.type = 1 -- depending on the type of `type`
LEFT JOIN domain_entities d ON e.id = d.id AND e.type = 2
Righto, so as suggested in the comment to the answer by #UsagiMiyamoto, there is a way to do this that allows declaration of entity types, with cascading. Note that this solution doesn't support unlimited entity types, as we need to maintain concrete FK constraints. There is a way to do this with unlimited entity types, but involves triggers and quite a bit of nastiness.
Here's the easy to understand solution:
-- Start with a test schema
DROP SCHEMA IF EXISTS "entityExample" CASCADE;
CREATE SCHEMA IF NOT EXISTS "entityExample";
SET SEARCH_PATH TO "entityExample";
-- We'll need this to enforce constraints
CREATE OR REPLACE FUNCTION is_entity_type(text, text) returns boolean as $$
SELECT TRUE WHERE $1 = $2
;
$$ language sql;
-- Unique entity types
CREATE TABLE "entityTypes" (
name TEXT NOT NULL,
CONSTRAINT "entityTypes_ukey" UNIQUE ("name")
);
-- Our client entities
CREATE TABLE clients (
id integer PRIMARY KEY,
name TEXT NOT NULL
);
-- Our domain entities
CREATE TABLE domains (
id integer PRIMARY KEY,
name TEXT NOT NULL
);
-- Our overaching entities table, which maintains FK constraints against clients and domains
CREATE TABLE entities (
id serial PRIMARY KEY,
"entityType" TEXT NOT NULL,
"clientID" INTEGER CHECK (is_entity_type("entityType", 'client')),
"domainID" INTEGER CHECK (is_entity_type("entityType", 'domain')),
CONSTRAINT "entities_entityType" FOREIGN KEY ("entityType") REFERENCES "entityTypes" (name) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT "entities_clientID" FOREIGN KEY ("clientID") REFERENCES "clients" (id) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT "entities_domainID" FOREIGN KEY ("domainID") REFERENCES "domains" (id) ON DELETE CASCADE ON UPDATE CASCADE
);
-- Our albums table, which now can have one owner, but of a dynam ic entity type
CREATE TABLE albums (
id serial PRIMARY KEY,
"ownerEntityID" integer,
name TEXT NOT NULL,
CONSTRAINT "albums_ownerEntityID" FOREIGN KEY ("ownerEntityID") REFERENCES "entities"("id")
);
-- Put the entity type in
INSERT INTO "entityTypes" ("name") VALUES ('client'), ('domain');
-- Enter our clients and domains
INSERT INTO clients VALUES (1, 'clientA'), (2, 'clientB');
INSERT INTO domains VALUES (50, 'domainA');
-- Make sure the clients and domains are registered as entities
INSERT INTO entities ("entityType", "clientID")
SELECT
'client',
"clients".id
FROM "clients"
ON CONFLICT DO NOTHING
;
INSERT INTO entities ("entityType", "domainID")
SELECT
'domain',
"domains".id
FROM "domains"
ON CONFLICT DO NOTHING
;
If you don't like the idea of inserting twice (once in client, once in entites, for example) you can have a trigger on inserts in the clients table, or alternately create an insert function that inserts to both tables at once.

MySQL ignoring duplicates on non-primary key

I have a table created by this SQL statement:
CREATE TABLE employees (
id INTEGER NOT NULL AUTO_INCREMENT,
name VARCHAR(20),
PRIMARY KEY (id)
);
I would like to insert into the table using something like
INSERT IGNORE INTO employees (name) values ('foo');
but for that statement to do nothing if there is already a person with a name 'foo' in the table. Is there a statement out there that ignores duplicates on a field other than a primary key or a field that is defined as unique?
INSERT INTO employees (name)
SELECT "foo" name FROM (select count(*) c
from employees
where name = "foo"
having c = 0) x;
You should have an index on name for efficiency. I'm not sure why you don't want to make it a unique index.
FIDDLE

Why don't I get any output from my relation table?

I have created 'students' table where 'sid' is the primary key and I have inserted many values into sid. I have created a second table called 'courses' and it has a primary key 'cid' I have entered values for cid as well. Now, I want to create a relation table called 'enroll' which I have done like-
create table enroll(
grade char(2),
sid int not null,
cid int not null,
primary key(sid,cid),
foreign key (cid) references courses(cid) on delete cascade,
foreign key (sid) references students(sid) on delete cascade
);
Now, when I try to view the table using select * from enroll;
I don't get any output. It says "0 rows returned". Why is this? Isn't it supposed to have all the values of sid and cid from the other tables?
In Order to create a new table from values in your other table you can do something like this:
CREATE TABLE new_table AS (SELECT * FROM old_table);
The select statement will be the fields that will be pulled.
You can rename the columns like: Select [field name] as [what you want field name to be]
For More information read this article
Anyway for your particular case:
Create table enroll AS (Select s.sid AS 'Sid', c.cid AS 'Cid' from courses c inner join students s on c.something = s.something)
replace '.something' with the id of the student
you just created the table structure, the schema, your table is empty, so you dont get any results.