Get columns from one table to another - sql

So I'll create a combination of all first names and all surnames from a table (Person).
insert into tabell_med_navn
select f.fornavn, e.etternavn
from person f cross join person e
These combinations should then be added to a table I have made earlier.
create table tabell_med_navn (
id int not null auto_increment,
fornavn varchar(40) null,
etternavn varchar(40) null,
primary key (id)
);
It is when I am trying to send the combination over it fails. Anybody know why it fails?

List the columns being inserted:
insert into tabell_med_navn (fornavn, etternavn)
select f.fornavn, e.etternavn
from person f cross join
person e;
This will assign a default value to the id column.

Related

Is there a way to relationship between two table which table one has 3 unique keys and table two has 2 unique keys in SQL Server?

I want to create relation between two tables, here's my table structure
Table1:
ID INT PrimaryKey AUTO_INCREMENT,
CountryCode INT UNIQUE,
Division VARCHAR(4) UNIQUE,
SubDivision VARCHAR(10) UNIQUE
Table2:
ID INT PrimaryKey AUTO_INCREMENT,
CountryCode INT UNIQUE,
Division VARCHAR(4) UNIQUE,
ReportNo VARCHAR(10) UNIQUE
Table1:
ID |CountryCode |Division |SubDivision
-------+------------------+--------------+-----------
1 |IDN |A |A-1
2 |IDN |B |B-1
3 |IDN |B |B-2
Table2
ID |CountryCode |Division |ReportNo
-------+------------------+--------------+-----------
1 |IDN |A |Re001
2 |IDN |A |Re002
3 |IDN |B |Re003
I want to create a relationship between those two tables which table2 (CountryCode, Division) refers to table1 (CountryCode, Division).
So when I want to delete in table1 with CountryCode = IDN and Division = A, SQL will prompt error when table2 contains CountryCode = IDN and Division = A.
I had tried to create a relationship between those two tables, but SQL Server always throws this error:
The column in table 'table1' do not match an existing primary key or unique constraint
Can anyone guide me how can I create a relationship between those two tables?
Thanks in advance
You can't do it this way. SQL Server requires a unique constraint (or primary key constraint) on the target of a foreign key - and you have duplicates in the source table.
For this to work, you would need to have a separate table that references all possible (CountryCode, Division) combinations. Actually, your whole schema should be normalized into something like:
-- "top" table that stores the countries
create table countries (
country_id int primary key
name varchar(100)
);
-- the table that stores the divisions
create table divisions (
division_id int primary key,
country_id int references countries(country_id),
name varchar(100)
);
-- the table that stores the subdivisions
-- this corresponds to "table1" in your question
create table subdivisions (
subdivision_id int primary key,
division_id int references divisions(division_id),
name varchar(100)
);
-- the table that stores the reports
-- this corresponds to "table2" in your question
create table reports (
report_id int primary key,
division_id references divisions(division_id),
name varchar(100)
);
You can make the primary keys automatic by using identity columns (which is the SQL Server equivalent for MySQL's AUTO_INCREMENT).
As an example, here is how you would generate the current output that you are showing for the subdivisions:
select
sd.id,
c.name country,
d.name division,
sd.name subdivision
from subdivisions sd
inner join divisions d on d.division_id = sd.division_id
inner join countries c on c.country_id = d.country_id
As GMB has answered you cannot do it in this way because of the duplicates. GMB's answer is the best way to solving your problem. If for some reason you cannot follow his advice then maybe my answer would help.
You could use a composite primary key on the columns CountryCode, Division, SubDivision. Then add subdivision to Table2. And then reference this primary key in the foreignkey restraint. (notice that my example throws an error on purpose to show that the value cannot be deleted)
DROP TABLE IF EXISTS Table2;
DROP TABLE IF EXISTS Table1;
CREATE TABLE Table1
(ID INT IDENTITY(1,1)
, CountryCode CHAR(3)
, Division VARCHAR(4)
, SubDivision VARCHAR(10)
, CONSTRAINT PK_Table1 PRIMARY KEY(CountryCode, Division, SubDivision)
)
INSERT INTO Table1(CountryCode, Division, SubDivision)
VALUES ('IDN', 'A', 'A-1')
, ('IDN', 'B', 'B-1')
, ('IDN', 'B', 'B-2');
CREATE TABLE Table2
(ID INT IDENTITY(1,1) PRIMARY KEY
, CountryCode CHAR(3)
, Division VARCHAR(4)
, SubDivision VARCHAR(10)
, ReportNo VARCHAR(10)
, CONSTRAINT FK_CountryDivision FOREIGN KEY(CountryCode, Division, SubDivision) REFERENCES Table1(CountryCode, Division, SubDivision)
);
INSERT INTO Table2(CountryCode, Division, SubDivision, ReportNo)
VALUES ('IDN', 'A', 'A-1', 'Re001')
, ('IDN', 'B', 'B-1', 'Re002')
, ('IDN', 'B', 'B-2', 'Re003');
DELETE FROM Table1
WHERE Division = 'A';
Of course this change could add a whole set of new problems for instance when a report is for the whole division what should the subdivision value then be.
ps. i had to change up the example tables a bit because the values did not match, ie string values into an int column.
SQL fiddle
thank you for the all greats answer.
But in my design I can't doing this, because I has been wrong at the first time.
And the greats answer was from Mr. #10676716 #GMB.
-- "top" table that stores the countries
create table countries (
country_id int primary key
name varchar(100)
);
-- the table that stores the divisions
create table divisions (
division_id int primary key,
country_id int references countries(country_id),
name varchar(100)
);
-- the table that stores the subdivisions
-- this corresponds to "table1" in your question
create table subdivisions (
subdivision_id int primary key,
division_id int references divisions(division_id),
name varchar(100)
);
-- the table that stores the reports
-- this corresponds to "table2" in your question
create table reports (
report_id int primary key,
division_id references divisions(division_id),
name varchar(100)
);
Thanks again Mr. GMB.

SQL SERVER - Violation of UNIQUE KEY Constraint

I'm trying to insert distinct values into a table using INSERT SELECT.
This is my Query
INSERT INTO oltp.Region(Region_Name,Country_Id)
(SELECT DISTINCT region,country_id FROM csv.Neighbourhoods, oltp.Country)
These are the tables
oltp.Country
csv.Neighbourhoods
I want to have a table which shows the Region name and the Country FK in which they come from.
These are the table creations
CREATE TABLE oltp.Country
(Country_Id int NOT NULL PRIMARY KEY IDENTITY(1,1),
Country_Name nvarchar(255) NOT NULL UNIQUE)
CREATE TABLE oltp.Region
(Region_Id int NOT NULL PRIMARY KEY IDENTITY(1,1),
Region_Name nvarchar(255) NOT NULL UNIQUE,
Country_Id int FOREIGN KEY REFERENCES oltp.Country(Country_Id))
You need a JOIN!
INSERT INTO oltp.Region (Region_Name,Country_Id)
SELECT DISTINCT n.region, c.country_id
FROM csv.Neighbourhoods n JOIN
oltp.Country c
ON n.country = c.country_name;
Never use commas in the FROM clause. Always use proper, explicit, standard, readable JOIN syntax.
Also, you should be storing the country id in the Neighbourhoods table, not the name.

How do i fill my table with data from 3 different tables?

So I am working on a football world cup database. These are my important tables:
CREATE TABLE Countries(
Cid SERIAL PRIMARY KEY,
Name VARCHAR(256) NOT NULL UNIQUE
);
CREATE TABLE Stadiums(
Sid SERIAL PRIMARY KEY,
Name VARCHAR(256) NOT NULL UNIQUE,
Cid INT REFERENCES Countries NOT NULL
);
CREATE TABLE Groups(
Gid SERIAL PRIMARY KEY,
Name VARCHAR(64) NOT NULL,
TYear SMALLINT REFERENCES Tournaments NOT NULL
);
CREATE TABLE Teams(
Tid SERIAL PRIMARY KEY,
Cid INT REFERENCES Countries NOT NULL,
Gid INT REFERENCES Groups NOT NULL
);
CREATE TABLE Matches(
Mid INT PRIMARY KEY,
HomeTid INT REFERENCES Teams NOT NULL,
VisitTid INT REFERENCES Teams NOT NULL,
HomeScore SMALLINT NOT NULL,
VisitScore SMALLINT NOT NULL,
MatchDate DATE NOT NULL,
MatchType VARCHAR(64) NOT NULL,
Sid INT REFERENCES Stadiums NOT NULL
);
CREATE TABLE tempmatches(
year INTEGER,
host_country VARCHAR(255),
match_id INTEGER,
type VARCHAR(255),
date DATE,
location1 VARCHAR(255),
team1 VARCHAR(255),
team2 VARCHAR(255),
score1 INTEGER,
score2 INTEGER
);
so my current problem is that I need to populate the columns HomeTid and VisitId of the Matches table with the tid's from the team's table that corresponds with the country of that team from the countries table but I'm not sure how to do that. I tried a few queries but none of them seemed to work. Has anyone an idea on how to solve this?
Using JOIN keyword you can combine 2 tables data.
Here, in this case, you have to use 3-way join.
Eg:
3-way JOIN can be used in this way:
SELECT * FROM table1 JOIN table2 ON table1.col1=table2.col2 JOIN table3 ON table3.col3=table.col1;
Here the 2 tables will get joined based on the columns mentioned after the "ON" keyword.
Here is a reference link in which JOIN is explained clearly
https://www.w3schools.com/sql/sql_join.asp
Use JOIN operation. In SQL it helps to combine several tables(queries) in one

Calculate a value with other values

Let's make it simple:
USE Example1
CREATE TABLE Person
(PersonID int PRIMARY KEY IDENTITY(1,1),
FirstName nchar(20) NOT NULL,
LastName nchar(20) NOT NULL,
Salary money NOT NULL
)
CREATE TABLE Student
(StudentID int PRIMARY KEY IDENTITY(1,1),
FirstName nchar(20) NOT NULL,
LastName nchar(20) NOT NULL,
FatherID int NOT NULL,
MotherID int NOT NULL,
CONSTRAINT fk_Student_FatherID FOREIGN KEY (FatherID)
REFERENCES Person(PersonID),
CONSTRAINT fk_Student_MotherID FOREIGN KEY (MotherID)
REFERENCES Person(PersonID)
)
CREATE TABLE Registration
(RegistrationID int PRIMARY KEY IDENTITY(1,1),
StudentID int NOT NULL,
Date datetime NOT NULL,
MonthlyPayment ??????????
CONSTRAINT fk_Registration_StudentID FOREIGN KEY (StudentID)
REFERENCES Student(StudentID)
)
INSERT INTO Person VALUES ('John','Doe','1000')
INSERT INTO Person VALUES ('Mary','Poppins','800')
INSERT INTO Student VALUES ('Gary','Doe', 1, 2)
INSERT INTO Registration VALUES (1, getdate(),???)
I have a student that is going to make a registration in a school and have a monthly payment that is going do be FatherSalary*0.5 + MotherSalary*0.5 but I don't know how to make that happen. I'm new in SQL and maybe this is simple and I should know how to make it, but I don't and I need help.
Are you sure you need MonthlyPayment column in your table?
You can create table Registration without MonthlyPayment field and then create a view
create view vw_Registration
as
select
R.RegistrationID,
R.StudentID,
R.Date,
F.Salary * 0.5 + M.Salary * 0.5 as MonthlyPayment
from Registration as R
left outer join Student as S on S.StudentID = R.StudentID
left outer join Person as F on F.PersonID = S.FatherID
left outer join Person as M on M.PersonID = S.MotherId
SQL FIDDLE EXAMPLE
If the expression "FatherSalary*0.5 + MotherSalary*0.5" will not change, then you can use trigger i suppose.Your trigger will check the inserts to your Registration table. At the time of an insert, it will get the student id, then using this id it will get the necessary data from your student table and your Person table. At that moment, you will have access to the Money column for both father and mother. Calculate the result, and let the trigger to the insert for you.
A view sounds good at first hand, but I can imagine a scenario where you want to calculate a monthly payment based on the data available at a certain point in time so the monthly payment does not change everytime the father or mother has a change in salary...
In that case you can use this:
INSERT INTO Registration
(StudentID, Date, MonthlyPayment)
SELECT S.StudentID, getdate(), ISNULL(F.Salary, 0) * 0.5 + ISNULL(M.Salary, 0) * 0.5
FROM Student as S
left outer join Person as F on F.PersonID = S.FatherID
left outer join Person as M on M.PersonID = S.MotherId
WHERE S.StudentID = 1
SQL Fiddle

How to select IDs from a table if two conditions in other tables match

I am developing a user feedback system using ASP.NET and C#. I have multiple tables and am trying to populate dropdown lists so that the feedback can be filtered.
My tables:
CREATE TABLE tblModules
(
Module_ID nvarchar(10) PRIMARY KEY,
Module_Title nvarchar(MAX) NOT NULL
);
CREATE TABLE tblQuestions
(
Q_ID int PRIMARY KEY IDENTITY(1,1),
Question_Text varchar(1000) NOT NULL
);
CREATE TABLE tblFeedback
(
Submission_ID int PRIMARY KEY IDENTITY(1,1),
Username varchar(100) NOT NULL,
Domain varchar(50) NOT NULL,
DateTime_Submitted datetime NOT NULL
Module_ID nvarchar(10)
FOREIGN KEY (Module_ID) REFERENCES tblModules (Module_ID);
);
CREATE TABLE tblAnswers
(
Q_ID int NOT NULL,
Submission_ID int NOT NULL,
Answer_Text varchar(max),
FOREIGN KEY (Q_ID) REFERENCES tblQuestions(Q_ID),
FOREIGN KEY (Submission_ID) REFERENCES tblFeedback(Submission_ID)
);
I have two dropdown lists. First one is populated with all modules from a table. The second needs to be populated with Questions from tblQuestions but only if any answers to it exist (therefore if the Question ID 'Q_ID' exists in tblAnswers).
I can get the selectedModuleID from the first dropdown list. I have a List of all Questions referenced by Q_ID in tblAnswers. How do I crossreference this list with the module ID?
Each feedback submission gets a Submission ID and Module ID.
You want:
questions that have answers
questions that have a module parent (via tblfeedback)
So, my guess at what you want:
SELECT
*
FROM
tblQuestions Q
WHERE
EXISTS (SELECT *
FROM
tblAnswers A
JOIN
tblFeedback F ON A.Submission_ID = F.Submission_ID
WHERE
Q.Q_ID = A.Q_ID AND F.Module_ID = #moduleID)
This should do the trick...
SELECT Q_ID, Question_Text tblQuestions a
WHERE EXISTS (SELECT NULL FROM tblAnswers a WHERE a.Q_ID = q.Q_ID)