Show correct result with SQL Joins - sql

Firstly, I am newbie to SQL (T-SQL), I would appreciate guidance with this.
I have 3 tables with values created as below.
CREATE Table StudentProject
(ID int identity (1,1) PRIMARY KEY,
ProjectName Varchar (30),
DueDate Date)
CREATE Table StudentName
(ID int identity (1,1) PRIMARY KEY,
StudentName Varchar (30))
CREATE Table StudentWork
(ID int identity (1,1) PRIMARY KEY,
ProjectID int,
StudentID int)
Insert Into StudentProject values
('Omega','1/2/2005'),('KingOmega','1/3/2000'),('Beast','1/6/2007'),
('DeltaMovie','3/7/2008')
Insert into StudentName values
('Roger'),('John'),('James'),('Juliet'),('William')
Insert into StudentWork values
(1,1),(1,2),(2,2),(2,3),(3,3),(3,4),(1,3)
The goal is to produce the below outcome but seems that i cant or i'm sure i'm doing something wrong.
SQL_Outcom
Please help.

SELECT StudentProject.ProjectName, StudentName.StudentName
FROM StudentWork
INNER JOIN StudentProject ON StudentProject.ID = StudentWork.ProjectID
INNER JOIN StudentName ON StudentName.ID = StudentWork.StudentID
You have 3 tables, try to recognize the "master table", then join them to other tables, after joining them you will have access to their columns.
Hello World :)
UPDATE:
In order to confirm Roger always with id 1 and all the other students in StudentName table, you need to use SET IDENTITY_INSERT which guarantee you the ordering of rows.
Instead of :
Insert into StudentName values
('Roger'),('John'),('James'),('Juliet'),('William')
Do this:
SET IDENTITY_INSERT StudentName ON
Insert into StudentName values
(1,'Roger'),(2,'John'),(3,'James'),(4,'Juliet'),(5,'William')
SET IDENTITY_INSERT StudentName OFF

You need to use inner join and in order to match the records related to each others:
Select p.ProjectName, s.StudentName from StudentName s
Inner join Studentwork sw on sw.studentid = s.Id
inner join StudentProject p on p.ID= sw.ProjectId
Order by P.ProjectName desc

You need inner join
Try this :
select s.StudentName,p.ProjectName from StudentName s
inner join StudentProject sp on sp.id= sw.ProjectId
inner join StudentWork sw on sw.studentid = s.id;

Related

Select Statement in SQL inheritance

CREATE TABLE User(
UserID int primary key,
Name varchar,
type int
);
CREATE TABLE Student(
UserID int primary key references User(UserID),
marks int
);
CREATE TABLE Lecture(
UserID int primary key references User(UserID),
salary int
);
Can someone help with with select statement for Student or lecture.
Both Lecture and Student tables are inheriting from User table,So I need to know how insert data and select data from these tables.
To query the tables, this would work:
SELECT u.[Name]
, s.marks
, l.salary
FROM [User] u
INNER JOIN Student s
ON u.UserId = s.UserId
INNER JOIN Lecture l
ON u.UserId = l.UserId;
However, if there are no records in the Student / Lecture tables yet, you should use LEFT Join instead.
As for inserting the data, you would need to use SCOPE_IDENTITY().
Insert into [User] (Name) values ('Melvin')
Get the identity of the UserId
DECLARE #userId INT;
SELECT #userId = SCOPE_IDENTITY ();
INSERT INTO Student
(
UserID
, Marks
)
VALUES
(userId, 5);
Update: Just noticed this was SQL Lite, which I'm not so familiar with, but it looks like it supports last_insert_rowid() instead of SCOPE_IDENTITY (), but you should get the gist of it.
If you want to select Student X:
SELECT *
FROM Student
WHERE UserID = X
If you want to select all Students and their User data, you'll want something like:
SELECT *
FROM User
JOIN Student ON User.UserID = Student.UserID
I don't understand your question but I think you need something like that
select Name, marks
from User as u, Student as s
inner join u.UserID == s.UserID;

How do I prevent duplicate table names when using cross join?

I have the following tables in a SQL database:
t_customers
ID_operator int primary key auto_incr
firstname varchar(30)
lastname varchar(30)
email varchar(100)
t_operator
ID_operator int primary key auto_incr
firstname varchar(30)
lastname varchar(30)
course varchar(10)
I have another table, which represents an order, in which I join both fields when querying another field:
SELECT
*, // table t_orders
t_customers.firstname,
t_customers.lastname,
t_operator.firstname AS operator_firstname,
t_operator.lastname AS operator_lastname
FROM
t_orders
CROSS JOIN
t_customers, t_operator
WHERE
id_orders IS 1;
I have tried to alleviate this by using the AS keyword and the new fields do get added, but I still have 2 fields named "firstname" and "lastname" in my query, preventing me from working with it correctly. Is there any solution besides renaming the tables?
Are you trying to do something like this?
SELECT o.*, // table t_orders
c.firstname, c.lastname,
op.firstname AS operator_firstname,
op.lastname AS operator_lastname
FROM t_orders o JOIN
t_customers c
ON o.id_customer = c.id_customer JOIN
t_operator op
ON c.id_operator = c.id_operator
WHERE id_orders = 1;

INSTEAD OF INSERT trigger & Identity column using view

I'm building a database that will store client data for a company. The tables in the DB are normalized, so I have multiple tables that are linked together using Foreign Key Constraints.
Microsoft Access will be used to interface with the database (as a frontend). To make things simpler, I created a view that joins all the required tables together so that end-users can query information without hassle.
The problem I've run into involves INSERTING information into this view. From my understanding, since I have multiple tables in my view, I have to use a trigger with an INSTEAD OF INSERT statement. I've created the trigger; however, I'm unsure how to work with the ID columns in the tables (these act as keys).
I have a MemberBasicInformation table that contains the client's DOB, Name, Gender, etc AND their MemberID. This ID is an IDENTITY column in the table, so it is generated automatically. The problem that I'm running into is that because the identity is automatically generated, I'm unable to grab the identity value that is generated after the insert into the MemberBasicInformation table and insert it into the other related tables. When I attempt to do so, I end up with a Foreign Key constraint violations.
I've tried using ##Identity and Scope_Identity() to no avail. I've listed my view and trigger to give you an idea of how things are set up. I would greatly appreciate if someone could point me in the right direction. I'm truly at a loss.
MEMBER view:
CREATE VIEW [dbo].[Member]
AS
SELECT
dbo.MemberBasic.MemberId, dbo.MemberBasic.FirstName,
dbo.MemberBasic.MiddleInitial, dbo.MemberBasic.LastName,
dbo.MemberBasic.FullName, dbo.MemberBasic.DateOfBirth,
dbo.Gender.Name AS Gender, dbo.MemberBasic.Address,
dbo.MemberBasic.Address2, dbo.MemberBasic.City,
dbo.MemberBasic.State, dbo.MemberBasic.ZipCode,
dbo.MemberBasic.PhoneNumber,
dbo.MemberBasic.SocialSecurityNumber,
dbo.MemberBasic.DriversLicense,
dbo.MemberBasic.EmployerIdentificationNumber,
dbo.MemberBasic.Notes,
dbo.FieldRep.Name AS FieldRepName,
dbo.MemberDetail.DateAssigned AS FieldRepDateAssigned,
dbo.MemberDetail.CPReceivedOn, dbo.MemberDetail.CredentialedOn,
dbo.MemberEligibility.IsActive, dbo.ICO.Name AS ICO,
dbo.MemberEligibility.StartDate AS EligibilityStartDate,
dbo.MemberEligibility.EndDate AS EligibilityEndDate,
dbo.MemberWorkerCompDetail.ExpirationDate AS WorkerCompExpirationDate,
dbo.MemberWorkerCompDetail.AuditDate AS WorkerCompAuditDate,
dbo.WorkerCompTier.Name AS WorkerCompTier,
dbo.MemberAttachment.AttachmentId,
dbo.MemberAttachment.Data AS AttachmentData
FROM
dbo.MemberAttachment
INNER JOIN
dbo.MemberBasic ON dbo.MemberAttachment.MemberId = dbo.MemberBasic.MemberId
INNER JOIN
dbo.MemberCaregiverAssignment ON dbo.MemberAttachment.MemberId = dbo.MemberCaregiverAssignment.MemberId
INNER JOIN
dbo.MemberDetail ON dbo.MemberBasic.MemberId = dbo.MemberDetail.MemberId
INNER JOIN
dbo.MemberEligibility ON dbo.MemberAttachment.MemberId = dbo.MemberEligibility.MemberId
INNER JOIN
dbo.MemberWorkerCompDetail ON dbo.MemberAttachment.MemberId = dbo.MemberWorkerCompDetail.MemberId
INNER JOIN
dbo.Gender ON dbo.MemberBasic.GenderId = dbo.Gender.GenderId
INNER JOIN
dbo.FieldRep ON dbo.MemberDetail.FieldRepId = dbo.FieldRep.FieldRepId
INNER JOIN
dbo.ICO ON dbo.MemberEligibility.ICOId = dbo.ICO.ICOId
INNER JOIN
dbo.WorkerCompTier ON dbo.MemberWorkerCompDetail.TierId = dbo.WorkerCompTier.TierId
GO
MEMBER trigger:
ALTER TRIGGER [dbo].[InsertNewMember]
ON [dbo].[Member]
INSTEAD OF INSERT
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO MemberBasic (FirstName, MiddleInitial, LastName, GenderId, DateOfBirth, Address, Address2, City, State, ZipCode, PhoneNumber, SocialSecurityNumber, DriversLicense, EmployerIdentificationNumber, Notes)
SELECT
FirstName, MiddleInitial, LastName, GenderId, DateOfBirth,
Address, Address2, City, State, ZipCode, PhoneNumber,
SocialSecurityNumber, DriversLicense,
EmployerIdentificationNumber, Notes
FROM
inserted
INNER JOIN
Gender ON Gender.Name = Gender;
INSERT INTO MemberDetail (MemberId, FieldRepId, DateAssigned, CPReceivedOn, CredentialedOn)
SELECT
MemberId, FieldRep.FieldRepId, FieldRepDateAssigned,
CPReceivedOn, CredentialedOn
FROM
inserted
INNER JOIN
FieldRep ON FieldRep.Name = FieldRepName;
INSERT INTO MemberEligibility (MemberId, ICOId, StartDate, EndDate)
SELECT
MemberId, ICOId, EligibilityStartDate, EligibilityEndDate
FROM
inserted
INNER JOIN
ICO ON ICO.Name = ICO;
INSERT INTO MemberWorkerCompDetail (MemberId, AuditDate, ExpirationDate, TierId)
SELECT
MemberId, WorkerCompAuditDate, WorkerCompExpirationDate, TierId
FROM
inserted
INNER JOIN
WorkerCompTier ON WorkerCompTier.Name = WorkerCompTier;
INSERT INTO MemberAttachment (MemberId, Data)
SELECT MemberId, AttachmentData
FROM Member
END
You can do this by using a table variable to hold the newly inserted IDs and all of the data that you're going to insert into the other tables. You need to do this because there's no way from just the first INSERTs data to join back to inserted in such a manner that you can match up the IDENTITY values with the rows that caused them to be generated.
We also have to abuse MERGE since INSERT doesn't let you include anything other than the target table in its OUTPUT clause.
I'm doing this on a toy example but hopefully you can see how to write it for your full table structures.
First, some tables:
create table dbo.Core (
ID int IDENTITY(-71,3) not null,
A varchar(10) not null,
constraint PK_Core PRIMARY KEY (ID)
)
go
create table dbo.Child1 (
ID int IDENTITY(-42,19) not null,
ParentID int not null,
B varchar(10) not null,
constraint PK_Child1 PRIMARY KEY (ID),
constraint FK_Child1_Core FOREIGN KEY (ParentID) references Core(ID)
)
go
create table dbo.Child2 (
ID int IDENTITY(-42,19) not null,
ParentID int not null,
C varchar(10) not null,
constraint PK_Child2 PRIMARY KEY (ID),
constraint FK_Child2_Core FOREIGN KEY (ParentID) references Core(ID)
)
go
And the view:
create view dbo.Together
with schemabinding
as
select
c.ID,
c.A,
c1.B,
c2.C
from
dbo.Core c
inner join
dbo.Child1 c1
on
c.ID = c1.ParentID
inner join
dbo.Child2 c2
on
c.ID = c2.ParentID
go
And finally the trigger:
create trigger Together_T_I
on dbo.Together
instead of insert
as
set nocount on
declare #tmp table (ID int not null, B varchar(10) not null, C varchar(10) not null);
merge into dbo.Core c
using inserted i
on
c.ID = i.ID
when not matched then insert (A) values (i.A)
output
inserted.ID /* NB - This is the output clauses inserted,
not the trigger's inserted so this is now populated */
,i.B,
i.C
into #tmp;
insert into dbo.Child1(ParentID,B)
select ID,B
from #tmp
insert into dbo.Child2(ParentID,C)
select ID,C
from #tmp
(And I would keep something like that comment in there since statements inside triggers that include OUTPUT clauses tend to be quite confusing since there are two inserted tables in play)
(It's also noteworthy that it doesn't really matter what you put in the ON clause of the MERGE, so long as you're sure that it will fail to make a match. You may prefer to have, say, just 1=0 if you think it makes it clearer. I just went cute on the fact that the trigger's inserted.ID will be NULL)
And now we do our insert:
insert into dbo.Together(A,B,C) values ('aaa','bbb','ccc')
go
select * from dbo.Together
And get the result:
ID A B C
----------- ---------- ---------- ----------
-71 aaa bbb ccc
Here is answer to your question "Getting Identity values to use as FK in an INSTEAD OF trigger"
https://dba.stackexchange.com/questions/34258/getting-identity-values-to-use-as-fk-in-an-instead-of-trigger

SQL : Join of three tables

I am new to SQL and am learning joins of tables now.
I am stuck at joining three tables.
(I have given the rows I have inserted to the tables also for your reference.)
My tables are
--Table1
create table sql_students(
stu_studentid int not null primary key,
stu_name varchar(100) not null,
stu_regnnumber bigint unique not null
)
--Rows inserted to Table1
insert into sql_students (stu_studentid,stu_name,stu_regnnumber) values (1,'John',194300)
insert into sql_students (stu_studentid,stu_name,stu_regnnumber) values (2,'Joy',959595)
insert into sql_students (stu_studentid,stu_name,stu_regnnumber) values (3,'Lucy',474848)
--Table2
create table sql_exam(
exa_examid bigint not null primary key,
exa_name varchar(100) not null,
exa_maxmark decimal(5,2) not null,
exa_minmarkreqdforpass decimal(5,2) not null,
exa_examscheduletime datetime not null
)
--Rows inserted into Table2
insert into sql_exam(exa_examid,exa_name,exa_maxmark,exa_minmarkreqdforpass,exa_examscheduletime) values (1,'Maths',100,40,'2012-10-10 10:00')
insert into sql_exam(exa_examid,exa_name,exa_maxmark,exa_minmarkreqdforpass,exa_examscheduletime) values (2,'English',75,35,'2012-10-11 10:00')
--Table3
create table sql_studentmarks(
stm_studentid int foreign key references sql_students(stu_studentid),
stm_examid bigint foreign key references sql_exam(exa_examid),
stm_mark decimal(5,2)
)
--Rows inserted into Table3
insert into sql_studentmarks(stm_studentid,stm_examid,stm_mark) values (1,1,80)
insert into sql_studentmarks(stm_studentid,stm_examid,stm_mark) values (2,1,90)
insert into sql_studentmarks(stm_studentid,stm_examid,stm_mark) values (3,1,40)
insert into sql_studentmarks(stm_studentid,stm_examid,stm_mark) values (1,2,70)
insert into sql_studentmarks(stm_studentid,stm_examid,stm_mark) values (2,2,60)
insert into sql_studentmarks(stm_studentid,stm_examid,stm_mark) values (3,2,17)
I need guidelines to get
All students who passed all exams
All students who attended all exams
All students and their mark difference in Maths and English.
Thanks in advance.
For #1
SELECT s.stu_name
FROM sql_studentmarks AS m
JOIN sql_students AS s ON m.stm_studentid = s.student_id
JOIN sql_exam AS x ON COUNT(m.stm_examid) = COUNT (x.stm_examid)
WHERE m.stm_mark >= x.exa_minmarkreqdforpass GROUP BY s.stu_studentid;
For #2 you can base on the exam count, perhaps creating a var in the select statement:
SELECT s.stu_name
FROM sql_studentmarks AS m
JOIN sql_students AS s ON m.stm_studentid = s.stu_studentid
RIGHT OUTER JOIN sql_exam AS x ON COUNT(m.stm_examid) = COUNT (x.stm_examid)
AND m.stm_examid IS NOT NULL
GROUP BY s.stu_student_id;
FOR #3 use the examples from above, simple joins will do:
SELECT s.stu_name, x.exa_name, m.stm_mark
FROM sql_studentmarks AS m
JOIN sql_students AS s ON m.stm_studentid = s.stu_studentid
JOIN sql_exam x ON m.stm_examid = x.exa_examid AND s.stu_studentid = x.exa_studentid;
The code below shows you the first two queries. Your joins are OK.. Try these in SQL Fiddle and then see if you can work the third query out
Query #1: (You were very close, just needed the distinct keyword)
select stm_studentid,stu_name
from sql_exam
join sql_studentmarks on exa_examid=stm_examid
and stm_mark>exa_minmarkreqdforpass
inner join sql_students on stu_studentid=stm_studentid
group by stm_studentid,stu_name
having count(*) = (select count(*) from sql_exam)
Query #2: -
The group by lets you count the number of exams taken.
The having lets you compare the count to number of exams available
select stu_name,count(*) as NumExamsTaken
from sql_studentmarks
join sql_students on stu_studentid=stm_studentid
group by stu_name
having count(*) = (select count(*) from sql_exam)
Query #3:
This should get you started
select stu_studentid,stu_name,
MG.stm_mark as MathGrade,
EG.Stm_mark as EnglishGrade
from sql_students
join sql_exam MATH on MATH.exa_name='MATHS'
join sql_exam ENG on ENG.exa_name='ENGLISH'
join sql_studentmarks MG on MG.stm_studentid=stu_studentid
and MG.stm_examid=MATH.exa_examId
join sql_studentmarks EG on EG.stm_studentid=stu_studentid
and EG.stm_examid=ENG.exa_examId

SQL Simple SELECT Query

create table Person(
SSN INT,
Name VARCHAR(20),
primary key(SSN)
);
create table Car(
PlateNr INT,
Model VARCHAR(20),
primary key(PlateNr)
);
create table CarOwner(
SSN INT,
PlateNr INT,
primary key(SSN, PlateNR)
foreign key(SSN) references Person (SSN),
foreign key(PlateNr) references Car (PlateNr)
);
Insert into Person(SSN, Name) VALUES ('123456789','Max');
Insert into Person(SSN, Name) VALUES ('123456787','John');
Insert into Person(SSN, Name) VALUES ('123456788','Tom');
Insert into Car(PlateNr, Model) VALUES ('123ABC','Volvo');
Insert into Car(PlateNr, Model) VALUES ('321CBA','Toyota');
Insert into Car(PlateNr, Model) VALUES ('333AAA','Honda');
Insert into CarOwner(SSN, PlateNr) VALUES ('123456789','123ABC');
Insert into CarOwner(SSN, PlateNr) VALUES ('123456787','333AAA');
The problem I'm having is the SELECTE query I wanna make. I wan't to be able to SELECT everything from the Person and wan't the include the PlateNr of the car he's the owner of, an example:
PERSON
---------------------------------
SSN NAME Car
123456789 Max 123ABC
123456787 John 3338AAA
123456788 Tom
----------------------------------
So, I want to be able to show everything from the Person table and display the content of CarOwner aswell if the person is in fact a CarOwner. What I have so far is: "SELECT * from Person, CarOwner WHERE Person.SSN = CarOwner.SSN;". But this obviously results in only showing the person(s) that are CarOwners.
Hope I explained me well enough, Thanks.
Try this:
SELECT p.*, c.*
FROM Person p
LEFT OUTER JOIN CarOwner co
ON p.SSN = co.SSN
LEFT OUTER JOIN Car c
ON co.PlateNr = c.PlateNr
Show SQLFiddle
P.S. I've changed the type of your primary key PlateNr (in varchar and not in int)
select ssn, name, car
from Person p
LEFT OUTER JOIN CarOwner co
ON p.SSN = co.SSN
LEFT OUTER JOIN Car c
ON co.PlateNr = c.PlateNr