SQL get all entries by ids - sql

I have 3 tables roughly like below:
create table user(
id integer primary key
)
create table post(
id integer primary key,
author integer,
foreign key (author) references user(id)
)
create table user_following(
id integer primary key,
follower integer,
followee integer,
foreign key (follower) references user(id),
foreign key (followee) references user(id)
)
these tables were created by ORM framework, I want to use raw SQL to get all posts by a user's followee, which can be multiple users. Can I do it in SQL?

If you know the follower's ID, the below statement will conduct a join and get the follower's followees' posts. You can replace the number 3 with any user id.
SELECT * FROM user_following AS a
JOIN post AS b ON a.followee = b.author
WHERE a.follower=3;

Something like this?
select p.*
from post p
join user_following uf on p.author = uf.followee
where uf.follower = 123;

select posts.*
from post posts
inner join [user] u_followee on u_followee.id = posts.author
inner join user_following ufo on ufo.followee = u_followee.id
inner join [user] u_follower on ufo.follower = u_follower.id
where u_follower.id = #USER_ID_WHOSE_FOLLOWEE_POSTS_REQUIRED

Related

How do I select data from a table consisting of a foreign key constraint?

I have two tables, User & Playlist
Table User:
CREATE TABLE IF NOT EXISTS User (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username VARCHAR(26) NOT Null UNIQUE,
email TEXT NOT Null UNIQUE,
password VARCHAR(100)
)
Table Playlist:
CREATE TABLE IF NOT EXISTS Playlist (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT,
image BLOB,
private NUMERIC,
playlistOwner VARCHAR(26),
FOREIGN KEY(playlistOwner) REFERENCES User(id)
)
Playlist table:
What I have tried with:
SELECT * FROM Playlist
JOIN Playlist
ON 10 = Playlist.playlistOwner
WHERE playlistOwner = ald;
Which gives the error:
Presumably, you intend something like this:
SELECT *
FROM Playlist pl JOIN
User u
ON pl.playListOwner = u.id
WHERE u.id = 10;
This is just a guess, but your question mentions two tables and the query references only one of them. Plus, a self-join doesn't seem particularly useful.
First, if you want the column playlistOwner of the table Playlist as foreign key that references the column id of the table User you should define with the same data type as the referenced column.
So the correct definition should be playlistOwner INTEGER:
CREATE TABLE IF NOT EXISTS Playlist (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT,
image BLOB,
private NUMERIC,
playlistOwner INTEGER,
FOREIGN KEY(playlistOwner) REFERENCES User(id)
)
and the values that you store in the column playlistOwner must be the ids of the users and not their usernames.
Now if you know the user's id there is no need for a join.
You simply do:
SELECT *
FROM Playlist
WHERE playlistOwner = 10;
If you know only the username then you join the tables:
SELECT p.*
FROM Playlist p INNER JOIN User u
ON u.id = p.playlistOwner
WHERE u.username = 'somename'
or with a subquery in the WHERE clause:
SELECT *
FROM Playlist
WHERE playlistOwner = (SELECT id FROM User WHERE username = 'somename')

How to relate tables SQL

I have three tables and i want to relate them, but i don't know what im doing wrong. If the way that im thinking is bad, can you correct me also?
I have clients table with Primary key as ID_c column,
create table clients
(
id_c INTEGER not null,
name VARCHAR2(20),
age INTEGER,
address VARCHAR2(20),
Primary key (id_c)
);
also i have products with primary key as ID_p column.
create table PRODUCTS
(
id_p NUMBER not null,
name_product VARCHAR2(30),
price NUMBER,
duration NUMBER,
primary key (id_p)
);
and now i create third
create table TRANSACTIONS
(
id_t NUMBER not null,
id_c NUMBER not null,
id_p NUMBER not null
primary key (ID_t),
foreign key (ID_c) references CLIENTS (ID_c),
foreign key (ID_p) references PRODUCTS (ID_p)
);
and now i want to see all records that are connected, so im trying to use that:
select * from transactions join clients using (id_c) and join products using (id_p);
but only what works is
select * from transactions join clients using (id_c);
is it relational database or im making something too easy, and too primitive? How can i do that to connect everything?
try this
select *
from transactions
inner join clients on transactions.id_c = clients.id_c
inner join products on transactions.id_p = products.id_p;
Are you just trying to join?
select * from transactions a
join clients b on a.id_c = b.id_c
join products c on a.id_p = c.id_p
If you want to join 3 tables, just write:
SELECT * FROM TRANSACTIONS t JOIN client c on t.id_c = c.id_c JOIN PRODUCTS p on t.id_p = p.id_p

Need a query to select specific comments with the name of the writer

I have a database contains 3 tables, as following:
CREATE TABLE users
(
id SERIAL PRIMARY KEY,
name VARCHAR(30) NOT NULL,
password VARCHAR(60) NOT NULL,
phone VARCHAR(10) NOT NULL,
email VARCHAR(30) UNIQUE
);
CREATE TABLE posts
(
id SERIAL PRIMARY KEY,
body TEXT NOT NULL,
user_id INTEGER REFERENCES users(id)
);
CREATE TABLE comments
(
id SERIAL PRIMARY KEY,
body TEXT NOT NULL,
post_id INTEGER REFERENCES posts(id),
user_id INTEGER REFERENCES users(id)
-- parent_id INTEGER REFERENCES comments(id)
);
I need a query to select all the comments for one specific post using the id of this post. What made me struggling is how to select the name of the user who wrote the comment!
This is what I tried :
select
c.body as cbody, p.body as pbody, c.user_id as user_id
from
users u
inner join
posts p on u.id = p.user_id
inner join
comments c on c.post_id = p.id
where
p.id=($1)
Any help??
I would use the Comments table as the first table in the FROM clause, since that's your main table for your query data. (Just personal preference, not a requirement.)
After that, I would join the Users table on Comments.user_id to get the comments' authors.
You probably do not want the post's body included with every comment, so I would leave that out.
So my query would look something like this:
SELECT c.body AS cbody, c.user_id AS user_id, u.name AS uname
FROM Comments c LEFT JOIN Users u ON u.id = c.user_id
WHERE c.post_id=($1);
An INNER JOIN might be valid too, but you need to be sure that Comments.user_id is always filled. When Comments.user_id is NULL, the comment will not be included in the queries result when INNER JOIN is used.

Write a query using INNER JOIN AND OR

I have a form and an insert button and when i click on the button - the fields goes in to these tables (i didn't put here all the fields because they are not important for my question).
The Tables:
CREATE TABLE SafetyAct (
SafetyAct_id int identity(1,1),
Username varchar(50),
SafetyType_id int,
constraint pk_SafetyAct_id
primary key (SafetyAct_id),
constraint fk_Users_SafetyAct
foreign key(Username)
references Users(Username)
on delete cascade
)
CREATE TABLE Product (
Product_id int identity(1,1) primary key,
SafetyAct_id int,
Cause_id int,
constraint fk_SafetyAct_Product
foreign key(SafetyAct_id)
references SafetyAct(SafetyAct_id)
on delete cascade,
constraint fk_Cause_Product
foreign key(Cause_id)
references Cause(Cause_id)
on delete cascade
)
CREATE TABLE SafetyIntervention (
SafetyIntervention_id int identity(1,1) primary key,
SafetyAct_id int,
Cause_id int,
constraint fk_SafetyAct_SafetyIntervention
foreign key(SafetyAct_id)
references SafetyAct(SafetyAct_id)
on delete cascade,
constraint fk_Cause_SafetyIntervention
foreign key(Cause_id)
references Cause(Cause_id)
on delete cascade
)
CREATE TABLE Cause (
Cause_id int primary key,
Cause_name varchar(80)
)
I want to write a query that shows the fields - SafetyAct_id and Cause_name.
in the Cause_name field i have a problem because i want that the query will show me the cause name drom the Product table or from the SafetyIntervension table (of course to connect it to the Cause table because i have only the cause_id - foriegn key in these tables) and i don't know how to write INNER JOIN and OR at the same query.
I am new with this so plase be patient.
Thank you!
SELECT SA.SafetyAct_id,
C.Cause_name
FROM SafetyAct SA
LEFT JOIN Product P
ON SA.SafetyAct_id = P.SafetyAct_id
LEFT JOIN SafetyIntervention SI
ON SA.SafetyAct_id = SI.SafetyAct_id
LEFT JOIN Cause C
ON ISNULL(P.Cause_id,SI.Cause_id) = C.Cause_id
An or is easy. So, based on Lamak's code:
SELECT SA.SafetyAct_id,
C.Cause_name
FROM SafetyAct SA LEFT JOIN
Product P
ON SA.SafetyAct_id = P.SafetyAct_id LEFT JOIN
SafetyIntervention SI
ON SA.SafetyAct_id = SI.SafetyAct_id LEFT JOIN
Cause C
ON C.Cause_id = P.Cause_id OR C.Cause_Id = SI.Cause_id;
--------------------------------^
You can just use OR in the ON condition.
However, it is often challenging for a SQL engine (SQL Server included) to optimize a join when the on condition includes or or functions on the columns used for the join. Hence, the following is often more efficient:
SELECT SA.SafetyAct_id,
COALESCE(Cp.Cause_name, Csi.Cause_Name) as Cause_Name
FROM SafetyAct SA LEFT JOIN
Product P
ON SA.SafetyAct_id = P.SafetyAct_id LEFT JOIN
SafetyIntervention SI
ON SA.SafetyAct_id = SI.SafetyAct_id LEFT JOIN
Cause Cp
ON Cp.Cause_id = P.Cause_id LEFT JOIN
Cause Csi
ON Csi.Cause_Id = SI.Cause_id;
If only some of the records have a cause of either type, then add:
WHERE Cp.Cause_Id IS NOT NULL OR Csi.Cause_Id IS NOT NULL;

How to create relationship between two non primary key entity in SQL Server

I have few tables where I need to link Patient card ID (PID) of table patient where primary key is patient_id with the PID field of other tables... how can I do that? help!
you can join them like
SELECT *
FROM [Patient] p
INNER JOIN [OtherTable] ot
ON p.pid = ot.patient_id;
You can use Foreign Keys
CREATE TABLE T
(
any_primary_key INT PRIMARY KEY,
[other attributes],
patient_id,
FOREIGN KEY (patiend_id) REFERENCES Patients.patient_id
)
Where Patients is a table that has the original patient_id which has to be declared as unique.