Select Statement in SQL inheritance - sql

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;

Related

Show correct result with SQL Joins

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;

How to replace LEFT outer join with INNER join in SQL?

I have a view on which I need to provide cluster Indexing the problem is in order to provide cluster indexing the it should not have any of the left or right outer joins , and I want to replace the LEFT outer join with INNER join , one of the ways which I can think of is to insert a dummy value with lets say -1 in the right table and by doing this even if all the Ids from the left table wont match Ids from the right table in INNER JOIN but since we have inserted -1 in the right table and we are using IsNULL(u.UserId,-1) it should return all the values from the left table but somehow this approach is not working.
create table Users(
UserId int,
UserName nvarchar(255)
)
insert into Users values(1,'sid429')
insert into Users values(2,'ru654')
insert into Users values(3,'dick231')
create table managers
(
caseId int,
CaseName nvarchar(255),
UserId int
)
insert into managers values (100,'Case1',1)
insert into managers values (101,'Case2',2)
insert into managers values (-1,NULL,-1)
select username from users u inner join managers m on m.UserId=IsNULL(u.UserId,-1)
Don't talk about indexes, but I think you could replace LEFT JOIN by INNER JOIN + UNION
select username from users u inner join managers m on m.UserId= u.UserId
UNION ALL
select username from users u WHERE NOT EXISTS (SELECT 1 FROM managers m WHERE m.UserId = u.UserId)
IsNull(u.UserId,-1) doesn't seem right - u.UserId is never null, since the absence of data is in the managers table - in this case, u.UserId will always have a value, but m.UserId might not, so IsNull(u.UserId, -1) won't work.
I'm intrigued to see a better answer, but I don't think you can do that - I think you eventually need to substitute the value conditionally to -1 if it doesn't exist in the other table, like this:
select username from users u
inner join managers m on m.UserId =
case when not exists(select * from managers where UserId = u.UserId)
then -1 else u.UserId end
This has the desired effect, but looking at the execution plan, won't help your performance issue.
You can replace a LEFT OUTER JOIN with an INNER JOIN if you add the missing values in the related table.
It has not worked for you because you have added a -1 value. But the not matching value on your INNER JOIN is a 3, not a null or a -1.
You can do so at runtime with an UNION, no need to permanently create those values as you have tried to do (inserting that -1 value) :
with expanded_managers as (
select CaseId, CaseName, UserId
from managers
union
select null, null, UserId
from users
where not exists (select * from managers where managers.UserId = users.UserId)
)
select UserName, CaseName
from users
inner join expanded_managers on expanded_managers.UserId = users.UserId
if you require only username it should be simple:
select distinct username from users u inner join managers m on m.UserId=u.UserId OR ( m.UserId=-1 AND u.userId = u.userId)
I have cleaned-up this part a bit. I had to guess the logical model, given that you did not specify any constraints.
create table Users (
UserId int not null
, UserName nvarchar(255) not null
, constraint pk_users primary key (UserId)
, constraint ak_users unique (UserName)
);
create table Cases (
CaseId int not null
, CaseName nvarchar(255) not null
, UserId int not null
, constraint pk_cases primary key (CaseId)
, constraint ak_cases unique (CaseName)
, constraint fk_cases foreign key (UserId)
references Users (UserId)
);
insert into Users values(1,'sid429') ;
insert into Users values(2,'ru654') ;
insert into Users values(3,'dick231');
insert into Cases values (100,'Case1',1);
insert into Cases values (101,'Case2',2);
This is mostly self-explanatory, but you have to understand that candidate keys (unique) for the result are: {UserID, CaseId}, {UserName, CaseName}, {UserID, CaseName}, {UserName, CaseId}. Not sure if you were expecting that.
with
R_00 as (
select UserId from Users
except
select UserId from Cases
)
select u.UserId
, u.UserName
, c.CaseId
, c.CaseName
from Users as u
join Cases as c on u.UserId = c.UserId
union
select u.UserId
, u.UserName
, (-1) as CaseId
, 'n/a'as CaseName
from Users as u
join R_00 as r on r.UserId = u.UserID
;
Another version of this, similar to other examples in the post.
select u.UserId
, u.UserName
, c.CaseId
, c.CaseName
from Users as u
join Cases as c on u.UserId = c.UserId
union
select u.UserId
, u.UserName
, (-1) as CaseId
, 'n/a' as CaseName
from Users as u
where not exists (select 1 from Cases as c where c.UserId = u.userId)
;

How to write correct sql request for my task

I have the tables : Users(id,name,...),Knowledge(id,name,...) and Courses(id,name....).
Each user has multiple "knowledge"(user and knowledge link by type ManyToMany).
For example user "User1" have 2 knowledge "1" and "2".
Course also link with knowledge by type ManyToMany. But knowledge in this case is requirement.
For example Course "Course 1" require knowledge "1" and "2", and user may access for this course.
Course "Course 2" required knowledge "1" and "3", and user have not access for this course.
I want to write correct sql command, which returned all courses, which can get user.
I use PostgresSql.
Sorry for my terrible English.
I tried this sql command for join course and knowledge:
select c.id as "Course id", k.requiredknowledge_id from course as c inner join courses_required_knowledges as k on k.course_id = c.id;
A similar command for join users and knowledge.
select u.id as "User id", k.knowledge_id from user_info as u inner join users_knowledge as k on k.userInfo_id = u.id where u.id = 1;
But i don't understand how to "combain" this commands for get result
select c.id as "Course", array_agg(k.requiredknowledge_id) as "Requiried knoweldge" , array_agg(uk.knowledge_id) as "User Knowledge"
from course as c
right join courses_required_knowledges as k on k.course_id = c.id
right join users_knowledge as uk on uk.userInfo_id = 1
group by c.id
having array_agg(k.requiredknowledge_id) <# array_agg(uk.knowledge_id);
This example work for me.
You're probably looking for something like this.
First let's create some test data:
create table course (id int primary key, name varchar(20));
insert into course (id, name) values
(1,'cooking'),
(2,'super hero'),
(3,'otaku');
create table knowledge (id int primary key, name varchar(30));
insert into knowledge (id, name) values
(4,'boil egg'),
(5,'toast bread'),
(6,'maintain secret identity'),
(7,'read');
create table courses_required_knowledges (id int primary key, course_id int, requiredknowledge_id int);
insert into courses_required_knowledges (id, course_id, requiredknowledge_id) values
(8,1,4),
(9,1,5),
(10,2,6),
(11,3,7);
create table user_info (id int primary key, name varchar(20));
insert into user_info (id, name) values
(12,'John Doe'),
(13,'Konata'),
(14,'Mega Mindy');
create table users_knowledge (id serial primary key, userInfo_id int, knowledge_id int);
insert into users_knowledge (userInfo_id, knowledge_id) values
(12,4),
(12,7),
(12,5),
(13,7),
(14,6),
(14,7),
(14,5);
The query below joins them on the correspondent fields.
With the user table cross joined (all to all) to the required courses.
select
-- course.id as course_id,
-- coursereq.requiredknowledge_id,
-- user_info.id as user_id,
course.name as course,
reqknow.name as required_knowledge,
user_info.name as username,
(case when users_knowledge.id is null then 'N' else 'Y' end) as user_meets_requirement
from courses_required_knowledges as coursereq
full outer join user_info on (1=1)
left join users_knowledge
on (user_info.id = users_knowledge.userInfo_id and
coursereq.requiredknowledge_id = users_knowledge.knowledge_id)
left join knowledge as reqknow
on (coursereq.requiredknowledge_id = reqknow.id)
-- left join knowledge as usrknow
-- on (users_knowledge.knowledge_id = usrknow.id)
left join course
on (coursereq.course_id = course.id)
where users_knowledge.id is null
order by
course.name, reqknow.name, user_info.name;
Which will give the requirements missed by the users to enroll in a course.
Result:
course required_knowledge username user_meets_requirement
cooking boil egg Konata N
cooking boil egg Mega Mindy N
cooking toast bread Konata N
super hero maintain secret identity John Doe N
super hero maintain secret identity Konata N

Insert values from one table to another table and other additional values

I have two tables Users and Friends. I want to copy two ID s for different users from Users table where their names already provided by C# code behind and put them into Friends table with their status column to be stored in one row at Friends table. Here is the query I made:
#id uniqueidentifier,
#username nvarchar(50),
#friendname nvarchar(50),
#friendstatus int
AS
INSERT INTO Friends (MYID,FriendId,ID,FriendStatus)
SELECT Users.ID,Users.ID,#id,#friendstatus
From Users cross join Friends as Friends_1
WHERE (Friends_1.MyID IN
(SELECT ID
FROM Users AS Users_1
WHERE (UserName IN (#username))))
AND (Friends_1.FriendId IN
(SELECT ID
FROM Users AS Users_1
WHERE (UserName IN (#friendname))))
I think this is what you are looking for
INSERT INTO Friends (MYID,FriendId,ID,FriendStatus)
SELECT Users.ID, Users.ID, #id, #friendstatus
From Users
inner join Friends as Friends_1 ON Users.ID = Friends_1.MyID
OR Users.ID = Friends_1.FriendId
WHERE UserName IN (#username, #friendname)
I think you can do it with a simple query like this:
insert into Friends (ID, MYID, FriendId, FriendStatus)
select
newid() ID, -- you can generate a new ID in SQL Server
-- #id ID -- if you generate ID in your c# code:
u1.ID MYID,
u2.ID FriendId,
#friendstatus FriendStatus
from
users u1
cross join
users u2
where
u1.UserName = #username
and
u2.UserName = #friendname;

How to get data by using different column values refrencing same table

I have two tables:
create table
books (
id int
,bookname text
);
create table
users(
id int
,name text
,book_1 int
,book_2 int
,book_3 int
);
Now, 'book_1', 'book_2', 'book_3' contains id of table 'books'.
I am trying to create a single query using join to get the all three book names with user name.
I am able to get one book name, but how will I get all the three books name?
SELECT user.name
,books.name
FROM user LEFT JOIN books ON books.id=user.book_1;
(This is giving me one book detail)
Using PostgreSQL.
I want result in one row. like
username, book_1_name, book_2_name, book_3_name
Don't want multiple rows.
You can use sub-selects to get bookname of each username in a single row (if id in table books is unique)
select name username
,(select bookname from books where id=book_1) book1_name
,(select bookname from books where id=book_2) book2_name
,(select bookname from books where id=book_3) book3_name
from users
> SQLFIDDLE DEMO
This may help you
SELECT user.name
,books.name
FROM user LEFT JOIN books ON books.id in (select id from books)
SELECT user.name
,books.name
FROM user LEFT JOIN books ON books.id=user.book_1
OR books.id=user.book_2
OR books.id=user.book_3;
join on all id's