Insert into table1 using data from staging_table1 and table2, while using staging_table1 to get the data from table2 - sql

Goal: Insert all data into a table from staging table. Each piece of data in the staging table has 2 names which can be found in a separate table. By using the 2 two names, I want to find their respective IDs and insert them into the foreign keys of the main table.
Question: How do I insert the data from a staging table into a table while using data from the staging to query IDs from a separate table?
Example tables:
TABLE location:
id int PRIMARY KEY,
location varchar(255) NOT NULL,
person_oneID int FOREIGN KEY REFERENCES people(person_id),
person_twoID int FOREIGN KEY REFERENCES people(person_id)
TABLE staging_location:
id int PRIMARY KEY,
location varchar(255) NOT NULL,
p1_full_name varchar(255) NOT NULL,
p2_full_name varchar(255) NOT NULL
TABLE people:
person_id int PRIMARY KEY,
first_name varchar(255) NOT NULL,
last_name varchar(255) NOT NULL,
full_name varchar(255) NOT NULL,
This question was the closest example to what I have been looking for. Though I haven't been able to get the query to work. Here is what I've tried:
INSERT INTO location(id,location,person_oneID,person_twoID)
SELECT (l.id,l.location,p1.person_oneID,p2.person_twoID)
FROM staging_location AS l
INNER JOIN people p1 ON p1.full_name = l.p1_full_name
INNER JOIN people p2 ON p2.full_name = l.p2_full_name
Additional info: I would like to do this in the same insert statement without using an update because of the number of locations being inserted. I'm using staging tables as a result of importing data from csv files. The csv file with people didn't have an ID field, so I created one for each person by following steps similar to the first answer from this question. Please let me know if any additional information is required or if I can find the answer to my question somewhere I haven't seen.

Use this code even though I do not know what your data structure is and a duplicate field may be inserted
INSERT INTO location(id,location,person_oneID,person_twoID)
SELECT (l.id,l.location,p1.person_id as person_oneID,p2.person_id as person_twoID)
FROM staging_location AS l
INNER JOIN people p1 ON p1.full_name = l.p1_full_name
INNER JOIN people p2 ON p2.full_name = l.p2_full_name

Related

How do I make the columns of one table not contain the columns of another table

I have a database with these two tables:
CREATE TABLE Photos(
photoId INT NOT NULL AUTO_INCREMENT,
userId INT NOT NULL,
url VARCHAR(200) NOT NULL UNIQUE,
uploadDate DATE NOT NULL,
title VARCHAR(80) NOT NULL,
description VARCHAR(400),
visibility ENUM ('Pública', 'Privada') NOT NULL,
PRIMARY KEY (photoId),
FOREIGN KEY (userId) REFERENCES Users (userId) ON DELETE CASCADE
);
CREATE TABLE InappropiateWords(
inappropiateWordId INT NOT NULL AUTO_INCREMENT,
word VARCHAR(80),
PRIMARY KEY (inappropiateWordId)
);
I'm asked to check that the title and/or description of a photo doesn't contain any inappropiate word. I guess I need to create a trigger but I don't know how to do it. Any help is appreciated. Thanks!
This is not a requirement that you can implement at the database level.
If you are really looking to ensure that the "description" or "title" does not contain inappropriate word, then
"What is Inappropriate" has to be defined?. This is step 1. You have a table (table 2) which I assume will store all inappropriate words.
Then when the program that inserts the picture and description/title is invoked, the code needs to take the title and description and parse the words and compare them against the "inappropriate_word" table and then decide which action to take.
The description or title might have a string of words in which case you may have to parse each word and check against the table(2).
This is not a take away solution but at least I hope this helps.
You can create a table variable that loads on page and perform a join to find those values.
CREATE TABLE #tbl_LinkedNames(
Name varchar(50)
, AssociatedNameNbr varchar(50)
, userId int
, inappropiateWordId int
)
INSERT INTO #tbl_LinkedNames(
NameNbr, AssociatedName, userId, inappropiateWordId )
VALUES
('A0001', 'badword', 1, 4),
('A0002', 'wORSEWORD', 2, 5),
('A0002', 'BADW00rds', 3, 6),
('A1001', 'badw', 4, 1),
('A2002', 'lengua', 5, 2),
('A3002', 'diferente', 6, 3)
SELECT * FROM #tbl_LinkedNames
From here it is a simple join based off the called stored procedure.
SELECT
*
FROM
Photos AS p
LEFT JOIN #tbl_LinkedNames AS t_LN ON
p.userId = t_LN.userID
AND
p.inappropiateWordId = t_LN.inappropiateWordId
LEFT JOIN InappropiateWords AS Ip ON
Ip.inappropiateWordId = t_LN.inappropiateWordId

Delete a record based on multiple table choices SQL

I'm trying to wrap my head around how to accomplish this Delete query. The goal is I'm trying to delete a client record (main table) based on if they don't have an insurance policy (another table) and if their needs description is "transportation" and importance values is LESS than 5. The needs is another table. They are all connected with foreign keys and SSN as the connector and Delete cascade is working properly. The query is partially working as is. If there is no insurance policy, the Client is being deleted correctly. However, the need description and importance value factors are not currently working. It will still delete if I have no insurance policy, but my importance description is another value other than transportation.
It's almost like I need 2 subqueries compare both Needs table and Insurance_Policy table for deletion, but I don't know how to do that.
The database I'm using is Azure Data Studio
Here is my current Procedure code:
DROP PROCEDURE IF EXISTS Option17;
GO
CREATE PROCEDURE Option17
AS
BEGIN
DELETE FROM Client
WHERE Client.SSN NOT IN (SELECT I.SSN
FROM Insurance_Policy I, Needs N
WHERE Client.SSN = I.SSN
AND Client.SSN = N.SSN
AND N.need_description = 'transportation'
AND N.importance_value < 5)
END
Also, here are my table structures:
CREATE TABLE Client
(
SSN VARCHAR(9),
doctor_name VARCHAR(60),
doctor_phone_no VARCHAR(10),
lawyer_name VARCHAR(60),
lawyer_phone_no VARCHAR(10),
date_assigned DATE,
PRIMARY KEY (SSN),
FOREIGN KEY (SSN) REFERENCES Person
ON DELETE CASCADE
);
CREATE TABLE Insurance_Policy
(
policy_id VARCHAR(10),
provider_id VARCHAR(10),
provider_address VARCHAR(100),
insurance_type VARCHAR(10),
SSN VARCHAR(9),
PRIMARY KEY (policy_id),
FOREIGN KEY (SSN) REFERENCES Client,
);
CREATE TABLE Needs
(
SSN VARCHAR(9),
need_description VARCHAR(60),
importance_value INT CHECK(importance_value > 0 and importance_value <11),
PRIMARY KEY(SSN,need_description),
FOREIGN KEY(SSN) REFERENCES Client
ON DELETE CASCADE
);
Here is a screenshot if the formatting didn't hold up on procedure.
enter image description here
Based on your answers, I believe this is the code you are looking for. If this is not working, let me know.
To explain a little, using an INNER join will eliminate the need for a couple of those WHERE conditions. INNER JOIN only returns records where it exists in both tables. Also there is no need to link to the Client table from within the subquery.
Also you want where it does not have a description of transportation with an importance of less than 5. Since you are pulling a list to leave alone, you do not want to include these records.
DROP PROC IF EXISTS Option17;
GO
Create proc Option17
AS
BEGIN
DELETE FROM Client
WHERE SSN NOT IN (
SELECT
N.SSN
FROM Needs N
INNER JOIN Insurance_Policy I ON N.SSN = I.SSN
WHERE NOT (N.need_description = 'transportation' AND N.importance_value < 5)
);
END
GO
I think you want separate conditions on Needs and Insurance_Policy. And I recommend NOT EXISTS, because it better handles NULL values:
DELETE c
FROM Client c
WHERE NOT EXISTS (SELECT 1
FROM Insurance i
WHERE c.SSN = i.SSN
) AND
EXISTS (SELECT 1
FROM Needs n
WHERE c.SSN = n.SSN AND
n.need_description = 'transportation' AND
n.importance_value < 5
);

How do I select insert into select a table which already has values in the primary key column without adding new rows?

I'm working on a database for my school project in which I have to produce a functional database by normalizing sample tables given to us.
One table I'm having trouble with is itineraries. I produce 3 tables from the normalization which are "Destinations", "Itineraries" and "Itinerary_Destinations".
The code for Destinations is:
create table Destinations
(
DestinationID varchar(5) primary key,
Name varchar(45)
);
The code for Itineraries is:
create table Itineraries
(
ItineraryID varchar(5),
Name varchar(45)
);
The code for the last table is:
create table Itinerary_Destinations
(
DI varchar(5) primary key,
ItineraryID varchar(5) foreign key references Itineraries(ItineraryID),
Itinerary_Name varchar(45),
DestinationID varchar(5) foreign key references Destinations(DestinationID),
Destination_Name varchar(45)
);
Data has already been inserted into all 3 tables with the exception of 'Destination_Name' and 'Itinerary_Name' columns. The code I'm attempting to use is returning as error. The code is shown below.
insert into Itinerary_Destinations (Itinerary_name)
select Name from Itineraries where
Itineraries.ItineraryID = ItineraryID;
The error it returns is
Msg 515, Level 16, State 2, Line 1 Cannot insert the value NULL into
column 'DI', table 'DDDAssignment.dbo.Itinerary_Destinations'; column
does not allow nulls. INSERT fails. The statement has been terminated.
Is there a method to accomplish the task of inserting the Destination_Name and Itinerary_Name without creating new records that require primary keys?
Or should I do it manually?
If you want to modify records which already exist, then you should be using an UPDATE rather than an INSERT:
UPDATE a
SET Itinerary_name = b.Name
FROM Itinerary_Destinations a
INNER JOIN Itinerary_name b
ON a.ItineraryID = b.ItineraryID;
But, if you do have some data which is not already logically associated with the Itinerary_Destinations table, then using an insert is appropriate.
use coalesce funtion in case null it will insert blank string, as your column does not allow null value thats why you got that error in your query
insert into Itinerary_Destinations (Itinerary_name)
select coalesce(Name,' ') from Itineraries where
Itineraries.ItineraryID = ItineraryID;

Generate a sub job

PS: Added a new image to better describe what i would like to achieve
As I couldn't find a way to phase the question, therefore it limits the possibility that I could get a ''ready'' solution, pardon me if this is available.
I am self-learning SQL, and would hope to gain some valuable lessons and information on how to write something as the following, greatly appreciated!
Seeking to write lines that allows me to add a master job (eg. 05-16-00000)
in each master job, there will be other "jobs" so it should generate (eg. 05-16-0000 - 01 .. XX). How can I have it written in a way?
[2
[]2
Just hold an id for each record and if a row has a parent, you set a parent_job_id to the corresponding id. Rows with no parent have the parent_job_id set to NULL.
CREATE TABLE `dbname`.`job`
( `id` BIGINT NOT NULL,
`description` VARCHAR(45) NULL,
`parent_job_id` BIGINT NULL,
PRIMARY KEY (`id`)
);
Get master jobs:
SELECT
`job`.`id`,
`job`.`description`,
`job`.`parent_job_id`
FROM
`testdb`.`job`
WHERE
`job`.`parent_job_id` IS NULL
;
If you are looking for children of job 3 replace the WHERE clause with
WHERE `job`.`parent_job_id` = 3
As you show in your later added example you want to m:n link the table with itself. Create a table with parent and child IDs.
CREATE TABLE `dbname`.`job_parent_child`
( `parent_id` BIGINT NOT NULL,
`child_id` BIGINT NOT NULL,
PRIMARY KEY (`parent_id`, `child_id`)
);
Same example - get all childs with parent job 3
SELECT * FROM `dbname`.`job` AS `child`
INNER JOIN `dbname`.`job_parent_child` AS `mn`
ON `child`.`id` = `mn`.`child_id`
WHERE `mn`.`parent_id` = 3
;
According to your last edit just select the job ids (and possibly other data if needed) from the table and iterate over the rows.
SELECT DISTINCT `JOB ID` FROM `jobs`;
Output the master job row of the html table. Then query with prepared statement
SELECT * FROM `jobs` WHERE `JOB ID` = ?;
Output all the rows. That's really all.

Putting a UPR page into a set of tables with SQL

I am trying to put a UPR pages into a set of tables for a database, so far I have come up with the following tables
UPR:
CODE,
NAME,
STRUCTURES,
APPENDICES,
DOCUMENTS
STRUCTURES:
STR_NAME,
STR_CODE
APPENDICES:
APP_NAME,
APP_CODE
DOCUMENTS:
DOC_NAME,
DOC_CODE
these tables are going to be used to store each part of the UPR's how ever I am having trouble trying to work out how to get all of the tables to link up so that they will all work together and have one way of pulling all relavent appendices, documents and structures together for one UPR code. I have a feeling I might be being blind here but cannot see to work out a way of doing this, any help would be hugely appreciated. Many thanks.
CREATE TABLE UPR
(
CODE NUMBER(9) NOT NULL,
NAME VARCHAR2(50)
)
;
ALTER TABLE UPR ADD CONSTRAINT PK_UPR
PRIMARY KEY (CODE)
USING INDEX
;
-- -------------------------------------
CREATE TABLE STRUCTURES
(
ID NUMBER(9) NOT NULL,
UPR NUMBER(9) NOT NULL,
SEQUENCE NUMBER(9) NOT NULL,
NAME VARCHAR2(50) NOT NULL
)
;
ALTER TABLE STRUCTURES ADD CONSTRAINT PK_STRUCTURES
PRIMARY KEY (ID)
USING INDEX
;
ALTER TABLE STRUCTURES ADD CONSTRAINT FK_STRUCTURES_UPR
FOREIGN KEY (UPR) REFERENCES UPR (CODE)
;
The structure of 'Appendix' and 'Document' would then follow the same pattern as 'Structures.
Does that help ?
edit
To build a complete UPR you would then do something like
SELECT S.NAME, D.SEQUENCE FROM STRUCTURES S WHERE CODE = :SomeCode
UNION SELECT A.NAME, D.SEQUENCE FROM APPENDIX A WHERE A.UPR = S.CODE
UNION SELECT D.NAME, D.SEQUENCE FROM DOCUMENT D WHERE D.UPR = S.CODE
ORDER BY 2
By the way ? What is a UPR? :)