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

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

Related

How to get a selection from tables related using a many-to-many relationship

I'm new to sql, I've looked at similar questions and answers on the platform, but still couldn't solve my problem.
I have three tables:
CREATE TABLE CartProducts (
Id PRIMARY KEY
ProductId int
Quanity int
)
CREATE TABLE CartCartProducts ( /* <-- many to many table */
CartProductsId PrimaryKey
CartId PrimaryKey
)
CREATE TABLE Cart (
Id PrimaryKey
UserId int
)
Before the query I have the following data:
I know the UserId
I know the ProductId
I know the CartId
I need to get the user's product with the passed product's id and user's id
I tried this:
SELECT
*
FROM
cart_products cp
JOIN cart_cart_products cm2m1 ON cm2m1.cart_id = %d
INNER JOIN cart_cart_products cm2m2 ON cm2m2.cart_products_id = cp.id
I know that using * is not recommended, I will remake it in the future
you always have to join all tables. with their columns, after that you have access to all columns and can extract all information needed.
the use of placehoder and parpameters, i omitted, as i don't know which langua you are using, but a quick search should find you a lot of answers
Following query fund you the quantity of a cart with number 1 of userid 1 and of the product 1
Fromhere you have all possibility, to search for all cart of a user, or all products he purchased
SELECT
cp.Quanity
FROM
cart_products cp
JOIN cart_cart_products cm2m1 ON cm2m1.cart_id = cp.iId
INNER JOIN cart c = c.Id = cm2m1.CartId
WHERE c.UserId = 1 AND c.id = 1 AND cp.ProductId = 1

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;

Insert into new table and a join table at the same time

I have a table called buyers and a table called sellers and I want to introduce a table called contacts that holds contact details for both buyers and sellers.
Focusing on the buyers first, I want a join table buyers_contacts to join buyers to contacts.
I want to initially fill the contacts table with one entry for each buyer. Then for each contact, I want to create a row in buyers_contacts.
How should I do this?
So far I have come up with this query (with incorrect syntax).
with buyer as (
select name, id from buyers
)
, new_contact as (
insert into contacts (name) select name from buyer
returning id as contact_id, buyer.id as buyer_id
)
insert into buyers_contacts (buyer_id, contact_id) values
(new_contact.buyer_id, new_contact.contact_id);
I have thought about doing this update in two stage, first creating a contact for each buyer, and and then inserting into the buyers_contacts table but I cannot rely on the buyers to have unique names.
I feel like this should be a solved problem but, there are no examples that seem to fit this situation.
Postgres is the database I am using.
Assuming there is some sequence behind the scenes that generates the contact Id when to create a new record:
create sequence contact_id;
I think all you have to do to add the buyers is this:
insert into contacts (contact_id, buyer_id)
select
nextval ('contact_id'), b.id
from buyer b
where not exists (
select null
from contacts c
where c.buyer_id = b.id
)
This will create new contact records at any time for only the buyers who have not already been added to the table.
You can also just rely on the default value:
insert into contacts (buyer_id)
select
b.id
from buyer b
where not exists (
select null
from contacts c
where c.buyer_id = b.id
)

SQL query - list of items in one table not in another

I need some help with a SQL query. I have a table of courses and a table that contains user id and course id, denoting courses that user has taken (might not have taken any; no entry in that table for that user id).
I need a query to return the list of courses not taken.
Course Category table
CategoryID
Caegory
Courses table
CourseID
CategoryID
CourseName
...
UserCourse table
UserID
CourseID
you can use not exists
Select *
From Courses c
Where Not Exists (Select 1 From UserCourse uc Where uc.CourseID = c.CourseID)
This will just list the course
select *
from Courses C
Left join CourseCategory cc on
cc.CategoryID = c.CategoryID
where CourseID not in (Select CourseID from UserCourse where UserID = 14)
what i need is for a given user id and course category, what courses within that category have not been taken by this user
(This should have been in the request by the way.)
So:
Select from courses.
Limit to the desired category.
Limit to courses not in the set of courses taken by the user.
The query:
select *
from courses
where categoryid = 123
and courseid not in (select courseid from usercourse where userid = 456);
Another way of writing same query, which will perform faster.
select C.CourseID,C.CategoryID
from Courses C
Left join CourseCategory cc on
cc.CategoryID = c.CategoryID
left join UserCourse uc
on C.CourseID=uc.CourseID
where uc.CourseID is null

How to fix this simple SQL query?

I have a database with three tables:
user_table
country_table
city_table
I want to write ANSI SQL which will allow me to fetch all the user data (i.e. user details including the name of the country of the last school and the name of the city they live in now).
The problem I am having is that I have to use a self join, and I am getting slightly confused.
The schema is shown below:
CREATE TABLE user_table (id int, first_name varchar(16), last_school_country_id int, city_id int);
CREATE TABLE country_table (id int, name varchar(32));
CREATE TABLE city_table (id int, country_id int, name varchar(32));
This is the query I have come up with so far, but the results are wrong, and sometimes, the db engine (mySQL), asks me if I want to show all [HUGE NUMBER HERE] results - which makes me suspect that I am unintentionally creating a cartesian product somewhere.
Can someone explain what is wrong with this SQL statement, and what I need to do to fix it?
SELECT usr.id AS id, usr.first_name, ctry1.name as loc_country_name, ctry2.name as school_country_name, city.name as loc_city_name
FROM user_table usr, country_table ctry1, country_table ctry2, city_table city
WHERE usr.last_school_country_id=ctry2.id
AND usr.city_id=city.id
AND city.country_id=ctry1.id
AND ctry1.id=ctry2.id;
Try this. I wrote it using ANSI syntax for clarity. I assume that you may not always have usr.city_id or usr.last_school_country_id, so I used a left outer join meaning you will always get usr records back regardless.
I also removed and ctry1.id=ctry2.id, because that would require the user's current city to be in the same country as their last_school_country_id, which I don't think is always the case.
SELECT usr.id AS id, usr.first_name, ctry1.name as loc_country_name, ctry2.name as school_country_name, city.name as loc_city_name
FROM user_table usr
left outer join city_table city on usr.city_id=city.id
left outer join country_table ctry1 on city.country_id=ctry1.id
left outer join country_table ctry2 on usr.last_school_country_id=ctry2.id
This query selects all users whose city is in the same country as their last school:
SELECT usr.id AS id, usr.first_name, ctry1.name as loc_country_name, ctry2.name as school_country_name, city.name as loc_city_name
FROM user_table usr
JOIN city
ON city.id = usr.city_id
JOIN country_table ctry1
ON ctry1.id = city.country_id
JOIN country_table ctry2
ON ctry2.id = usr.last_school_country_id
WHERE ctry1.id = ctry2.id
It is synonymous to your original query.
As long as all fields named id are primary keys, this query cannot return more records than there are in user_table.
Make sure that all id are PRIMARY KEYs and you don't have duplicates.
Could you please run these queries:
SELECT COUNT(*)
FROM user_table
SELECT COUNT(*), COUNT(DISTINCT id)
FROM city
SELECT COUNT(*), COUNT(DISTINCT id)
FROM country_table
and post the output here?
normally if you're joining 3 tables there will be two joining statements. always 1 less then the number of items being joined.
Never mind, I understand why you might need the join,
going to keep working at the code.
SELECT user_table.*, contry_table.*, city_table.* FROM user_table, country_table, city_table WHERE country_table.id = last_school_country_id AND city_id = city_table.id