How to use left outer join in my sql query? - asp.net

Here is my query:
ALTER PROCEDURE sp_logdetails
(
#bookid INT
)
AS
BEGIN
SELECT *
FROM book_lending
LEFT OUTER JOIN student ON student.id = book_lending.id
WHERE bookid = #bookid
END
When i execute above query, it shows only book_lending data, not the student data. Here is my screenshot
And it is my student table data screenshot:
May i know, how to get student data in which particular bookid. I used to set foreign key for book_lending id to student id.
Can anyone guide me to fix this?
Thanks,

Select the specific columns from joined table in your select list. Here bl and s is table alias for better redability. You need to select the columns you want and include them to your select list. below query will select all columns from both tables.
SELECT bl.*, s.*
FROM book_lending bl
LEFT OUTER JOIN student s ON s.id = bl.id
AND bl.bookid = #bookid

You got the fields mixed up in the join:
LEFT OUTER JOIN student ON student.id = book_lending.id
You try to match a student to book lending by ID of both - which is wrong.
Change the code to this and you will start getting results back:
SELECT *
FROM book_lending
LEFT OUTER JOIN student ON student.id = book_lending.studentid
WHERE bookid = #bookid

Related

Sqlite | How do I select records from two different tables using Case?

Edit
I would rather explicitly state my problem I'm facing rather than assuming the approach. There could be an easiest solution to my problem.
I need to select records by joining two different table based on the result from another table. And I have to use different joins based on the result from the first table.
If a particular record is present in the first table, I have two use inner join the first table whereas if it's not present, then I have to left join.
bool recordPresent = select exists (select * from firstTable where access_id = 13) as access
if (recordPresent)
results = select * from secondTable s left join firstTable f on f.access_id = s.access_id where f.access_id is null order by access_id
else
results = select * from secondTable s inner join firstTable f on f.access_id = s.access_id

Sqlite double left outer join with count

I have the following DB structure:
tbl_record(_id,_id_user,...)
tbl_photo(_id,_id_record,...)
tbl_note(_id,_id_record,...)
When listing the records of a specific user while counting the number of photos a record has, I use the following query, which works fine:
SELECT tbl_record._id, COUNT(tbl_photo._id_record) AS photo_count FROM tbl_record
LEFT OUTER JOIN tbl_photo ON tbl_record._id=tbl_photo._id_record
WHERE tbl_record._id_user=? GROUP BY tbl_record._id;
Now, I'd like to do the same as above, but also count the number of notes a record has:
SELECT tbl_record._id, COUNT(tbl_photo._id_record) AS photo_count, COUNT(tbl_note._id_record) AS note_count FROM tbl_record
LEFT OUTER JOIN tbl_photo ON tbl_record._id=tbl_photo._id_record
LEFT OUTER JOIN tbl_note ON tbl_record._id=tbl_note._id_record
WHERE tbl_record._id_user=? GROUP BY tbl_record._id;
The count of the 2nd query does not work properly when a record has >0 photos & >0 notes, e.g. 3 photos & 5 photos which results in a count of 15 (3*5) for each.
Any idea how to make the 2nd query return the proper counts?
Thanks!!
You might be able to filter out duplicates by using COUNT(DISTINCT some_id), but this would be inefficient.
Better use correlated subqueries:
SELECT _id,
(SELECT COUNT(*)
FROM tbl_photo
WHERE _id_record = tbl_record._id
) AS photo_count,
(SELECT COUNT(*)
FROM tbl_note
WHERE _id_record = tbl_record._id
) AS note_count
FROM tbl_record
WHERE _id_user = ?

How to perform Sql Join Query on more than two tables?

I have a table named "tbl_category" which contains the following fields:
category_id int auto_increment primary key,
category_title varchar(max),
category_description varchar(max) //is the foreign key in "tbl_sub_category"
And another table is "tbl_sub_category" which have the following fields:
sub_category_id int auto_increment primary key,
sub_cateogry varchar(max),
cateogry_id int auto_increment
Now, I want to display sub_category with its corresponding category_title. Can any help me out?
Use this query
SELECT c.category_title, s.sub_category
FROM tbl_category c
INNER JOIN tbl_sub_category s ON c.category_id = s.category_id
SELECT sub_category,category_title FROM tbl_category,tbl_sub_category
WHERE tbl_category.category_id=tbl_sub_category.category_id;
This is with a minor modification on the previous query, The previous queries would work fine if corresponding to each category an entry is available in subcategory table. If it is not the case, use outer join.
SELECT c.category_title, s.sub_category
FROM tbl_category c
LEFT OUTER JOIN tbl_sub_category s
ON c.category_id = s.category_id
CategoryID in subcategory table cannot be auto-increment.
SELECT
s.sub_category_id,
s.sub_cateogry,
c.category_title
FROM
tbl_sub_category s
INNER JOIN
tbl_category c
ON s.cateogry_id = c.category_id
The above example will only ever display items that are in the tbl_sub_category that have a corresponding foreign key in tbl_category. The INNER JOIN is stating to only return rows that have the foreign key relationship, while the FROM starts with tbl_sub_category which ensures we're only looking at sub categories. You can easily reverse these two so that the FROM is on the tbl_category and the INNER JOIN is on the tbl_sub_category which would produce the same results, but in this example you're being more explicit that you're interested in the sub categories and not the categories.

SQLite outer join column filtering

As a training exercise I'm working on a fictional SQLite database resembling League of Legends, and I need to perform a left outer join to get a table of all players and if they have skins that are not called 'Classic', return those too.
I currently have this query:
SELECT * FROM players
LEFT OUTER JOIN (SELECT * FROM playerchampions WHERE NOT championskin = 'Classic')
ON name = playername
Which returns what I am looking for, but also a lot of columns I don't want (player experience, player IP, player RP, playername in the playerchampions table. The code for the two tables is as following:
CREATE TABLE players (
name TEXT PRIMARY KEY,
experience INTEGER,
currencyip INTEGER,
currencyrp INTEGER
);
CREATE TABLE playerchampions (
playername TEXT REFERENCES players ( name ) ON UPDATE CASCADE,
championname TEXT REFERENCES champions ( name ) ON UPDATE CASCADE,
championskin TEXT REFERENCES skins ( skinname ) ON UPDATE CASCADE,
PRIMARY KEY ( playername, championname, championskin )
);
As I said, the query executes, but I can't use SELECT players.name, playerchampions.championname, playerchampions.championskin as the playerchampions columns are not given their proper table name when returned.
How do I fix this?
Try using aliases:
SELECT p.name, c.championskin FROM players p LEFT OUTER JOIN (SELECT pc.playername playername, pc.championskin championskin FROM playerchampions pc WHERE NOT pc.championskin = 'Classic') c ON p.name = c.playername;
Not sure if its exactly what you need, but it will get you closer...
SELECT * FROM players p LEFT OUTER JOIN playerchampions pc ON (p.name = pc.playername) WHERE NOT pc.championskin = 'Classic'

Querying 2/3 tables with one SQL statement

I have three tables: users, projects, user_project
user_project contains user_id, project_id and role_id, where user_id and project_id are both primary keys connected to projects.project_id and users.user_id.
I want to get the the name and surname of all the users from the users table that has to do with a certain project from the projects table through user_project.
What SQL statement do I have to use? I was thinking something like this:
SELECT
users.name, users.surname
FROM users
WHERE users.user_id = user_project.user_id AND projects.project_id = #parameter
I am using SQL Server 2012 and ASP.NET/VB.NET.
Db Diagram:
http://i.imgur.com/lrv52wO.png
SELECT users.name, users.surname
FROM users u
INNER JOIN user_project up
ON u.user_id = up.user_id
WHERE up.project_id = #parameter
You'll need to join to your other tables - either from Users through User_Project all the way to Projects if you want to base your selection on something in the Projects table:
SELECT
u.name, u.surname
FROM users u
INNER JOIN user_project up ON u.user_id = up.user_id
INNER JOIN project p ON p.project_id = up.project_id
WHERE p.project_name = 'something'
or at least to the link table, if you can use the project_id as criteria:
SELECT
u.name, u.surname
FROM users u
INNER JOIN user_project up ON u.user_id = up.user_id
WHERE up.project_id = #parameter
Update: assuming your Role table is connected to Users through again a link table Users_role then you need this to select role name, too:
SELECT
u.name, u.surname,
RoleName = r.Name
FROM users u
INNER JOIN user_project up ON u.user_id = up.user_id
INNER JOIN user_roles ur ON u.user_id = ur.user_id
INNER JOIN role r ON ur.role_id = r.role_id
WHERE up.project_id = #parameter
SELECT
users.name, users.surname
FROM users
inner join user_project
on users.user_id = user_project.user_id
WHERE user_project.project_id = #parameter
This should do it.
SELECT users.name, users.surname
FROM users
INNER JOIN user_project ON user_project.user_id = users.user_id
WHERE (user_project.project_id = #parameter)
The important line here is the line that starts INNER JOIN. You don't need the project table as the project_id column is in user_project. If you wanted to get the project name for example you would need the project table. You would do this by writing another INNER JOIN.
INNER JOIN project ON project.project_id = user_project.project_id
Now that you have joined you can access all the columns in the project table.

Resources