How to Left Join with Inner Join - mysql

I have a tables users and documents which has a many to many relationship with document_user (junction table). But my documents table has a column category_id that reference to categories table. So categories has a one to many relationship with documents. See screenshot below.
I want to join in my junction table the category_id under documents table.
This is my code so far.
SELECT DU.user_id, DU.document_id, DU.dateReceived FROM document_user DU
INNER JOIN documents D ON DU.document_id = D.id
INNER JOIN users S ON DU.user_id = S.id;
Result:

Add another join, as said in the comments:
SELECT DU.user_id, DU.document_id, DU.dateReceived, C.category_type
FROM document_user DU
INNER JOIN documents D ON DU.document_id = D.id
INNER JOIN users S ON DU.user_id = S.id
INNER JOIN categories C ON C.id = D.category_id;

Add an inner JOIN is always matct
SELECT DU.user_id, DU.document_id, DU.dateReceived FROM document_user DU
INNER JOIN documents D ON DU.document_id = D.id
INNER JOIN users S ON DU.user_id = S.id
INNER JOIN categoris on documents.category_id ) categories.id
or left if not
SELECT DU.user_id, DU.document_id, DU.dateReceived FROM document_user DU
INNER JOIN documents D ON DU.document_id = D.id
INNER JOIN users S ON DU.user_id = S.id
LEFT JOIN categoris on documents.category_id ) categories.id

Add D.category_id to select like so:
SELECT DU.user_id, DU.document_id, DU.dateReceived, D.category_id FROM

Related

How to join 4 tables with mysql

Sorry, now here is the code, basically, the first query returns me a tab which contains fk_id_produto, i wanted to join it with thee second one with the id_pedido
(SELECT fk_id_produto,fk_id_pedido, descricao_produto, valor_produto
FROM Pedido_Produto
INNER JOIN Produto ON pedido_produto.fk_id_produto = produto.id_produto);
INNER JOIN ON
(SELECT id_cliente,nome_cliente,id_pedido,valor_pedido,data_do_pedido A
FROM Cliente
INNER JOIN Pedido ON cliente.id_cliente = pedido.fk_id_cliente);
You can just do a join with the two selects that you have
SELECT *
FROM
(SELECT 1) as s1 inner join
(SELECT 2) as s2 on s1.id_pedido = s1.fk_id_pedido
SELECT *
FROM
(SELECT
fk_id_produto,
fk_id_pedido,
descricao_produto,
valor_produto
FROM
Pedido_Produto
INNER JOIN Produto
ON pedido_produto.fk_id_produto = produto.id_produto
) as s1
INNER JOIN
(SELECT
id_cliente,
nome_cliente,
id_pedido,
valor_pedido,
data_do_pedido A
FROM
Cliente
INNER JOIN Pedido
ON cliente.id_cliente = pedido.fk_id_cliente
) as s2
ON s1.id_pedido = s1.fk_id_pedido
BR
So you have four tables:
Products (P)
Clients (C)
Orders (O)
OrderProducts (OP)
SELECT
*
FROM
OP
JOIN
P ON P.ID = OP.P_ID
JOIN
O ON O.ID = OP.O_ID
JOIN
C ON C.ID = O.C_ID
That will produce one row for each OP and give you the product, order and client details

check if exist record in the another table

task; id
task_assign; id, task_id
task_state; id, assign_id
states; id, state_id, define_id
I want containing at selected IDs in other table
SELECT DISTINCT t.id,t.* FROM tasks AS t
INNER JOIN task_assign AS ta1 ON ta1.task_id=t.id
INNER JOIN task_state AS ts1 ON ts1.assign_id=ta1.id
INNER JOIN states AS s1 ON s1.id=ts1.state_id AND s1.define_id=14
INNER JOIN task_assign AS ta2 ON ta2.task_id=t.id
INNER JOIN task_state AS ts2 ON ts2.assign_id=ta2.id
INNER JOIN states AS s2 ON s2.id=ts2.state_id AND s2.define_id=21
.
.
.
INNER JOIN task_assign AS ta5 ON ta5.task_id=t.id
INNER JOIN task_state AS ts5 ON ts5.assign_id=ta5.id
INNER JOIN states AS s5 ON s5.id=ts5.state_id AND s5.define_id=25
this works but when multiplied request it slowing down. Is there another method?
SELECT
t.id
FROM
tasks t
INNER JOIN
task_assign ta1
ON ta1.task_id = t.id
INNER JOIN
task_state ts1
ON ts1.assign_id = ta1.id
INNER JOIN
states s1
ON s1.id = ts1.state_id
AND s1.define_id IN (14,25)
GROUP BY
t.id
HAVING
COUNT(DISTINCT s1.define_id) = 2
EDIT - to explain to the OP what this does...
This will first retrieve all records where the define_id is either 14 OR 25, but the HAVING clause will only allow the query to return those who have both.

Mysql query help. I need to make sure atleast one record is returning

I have a query that I know it should atleast return one row. How can i modify my follow query to make sure that album returns data. thanks for any help.
Query Here. I know that Album has a row and I need to return it.
select distinct p.*,
a.ID as parentalbumid,a.CreatorID as albumcreatorid,a.AlbumName,a.AlbumDescription,a.AlbumDefaultImageURL,a.Private,a.DateCreated,a.AdultContent,a.PasswordProtected,a.AllowTags,a.TypeID,a.AlbumAutoID,
mainuser.Username as mainuserusername,mainuser.ID as mainuserid,mainuser.PictureUrl as mainuserpictureurl,
c.ID as commentID,c.PhotoID as commentphotoid,c.OutputMessage,c.CommentDate,
t.ID as tagID,t.PhotoID as tagphotoid,t.UserID,t.TextTag,t.LeftLocation,t.TopLocation,
u.ID as userid,u.Username,u.FirstName,u.LastName,u.PictureUrl
from photos p
inner join albums a on a.ID = p.AlbumID
inner join users mainuser on mainuser.ID = p.UserID
left join comments c on c.PhotoID = p.ID
left join tags t on t.PhotoID = p.ID
left join users u on u.ID = c.CommentBy
where a.AlbumAutoID = 3
order by p.DateUploaded desc;
Use only LEFT JOINs (and put the table albums as the first table of your FROM):
select distinct p.*,
a.ID as parentalbumid,a.CreatorID as albumcreatorid,a.AlbumName,a.AlbumDescription,a.AlbumDefaultImageURL,a.Private,a.DateCreated,a.AdultContent,a.PasswordProtected,a.AllowTags,a.TypeID,a.AlbumAutoID,
mainuser.Username as mainuserusername,mainuser.ID as mainuserid,mainuser.PictureUrl as mainuserpictureurl,
c.ID as commentID,c.PhotoID as commentphotoid,c.OutputMessage,c.CommentDate,
t.ID as tagID,t.PhotoID as tagphotoid,t.UserID,t.TextTag,t.LeftLocation,t.TopLocation,
u.ID as userid,u.Username,u.FirstName,u.LastName,u.PictureUrl
from albums a
left join photos p on a.ID = p.AlbumID
left join users mainuser on mainuser.ID = p.UserID
left join comments c on c.PhotoID = p.ID
left join tags t on t.PhotoID = p.ID
left join users u on u.ID = c.CommentBy
where a.AlbumAutoID = 3
order by p.DateUploaded desc;

Regarding JOIN query in Mysql

Here is my database structure:
payment option:
mshiptype_id
paymopt_Id
membertopaymentoption:
member_Id
paymopt_Id
mshiptypes
mshiptype_name
mshiptype_id
timetable_id
timetables
timetable_id
timetable_Name
timeslots
timeslot_id
timeslot_name
timeslottotimetables
timeslot_id
timetable_id
I want to get the mshiptype_name and timeslot_name and timetable_name for single member
by using above tables
would any one give suggestions on join query......in mysql
SELECT mshiptype_name, timeslot_name, timetable_name
FROM mshiptypes ST
INNER JOIN paymentoption PO ON ST.mshiptype_id = PO.mshiptype_id
INNER JOIN membertopaymentoption MPO ON PO.paymopt_Id = MPO.paymopt_Id
INNER JOIN timetables TT ON ST.timetable_id = TT.timetable_id
INNER JOIN timeslottotimetables TTT ON TT.timetable_id = TTT.timetable_id
INNER JOIN timeslotss TS ON TTT.timeslot_id = TS.timeslot_id
WHERE MPO.member_id = <members_id>
I think this is what you want:
SELECT mshiptypes.mshiptype_name, timeslots.timeslot_name, timetables.timetable_Name
FROM membertopaymentoption
INNER JOIN paymentoption ON membertopaymentoption.member_Id=paymentoption.paymopt_Id
INNER JOIN mshiptypes ON paymentoption.mshiptype_id=mshiptypes.mshiptype_id
INNER JOIN timetables ON mshiptypes=timetable_id=timetables.timetable_id
INNER JOIN timesslottotimetables ON timetables.timetable_id=timeslottotimetables.timeslot_id
INNER JOIN timeslots ON timeslottotimetables.timeslot_id=timeslots.timeslot_id
WHERE membertopaymentoption.member_Id=$id
Note: replace $id in the WHERE clause with the actual memeber id
The trick is to identify fields common to two different tables, and try to find a path linking all the fields you want.
select
mtpo.member_Id,
mt.mshiptype_name,
ts.timeslot_name,
tt.timetable_name
from
payment_option po
left join membertopaymentoption mtpo on po.paymopt_Id = mtpo.paymopt_Id
left join mshiptypes mt on mt.mshiptype_id = po.mshiptype_id
left join timetables tt on tt.timetable_id= mt.timetable_id
left join timeslottotimetables tstt on tstt.timetable_id = tt.timetable_id
left join timeslots ts on ts.timeslot_id = tstt.timeslot_id
where
member_Id = 1 -- change this
Also, I suggest tidying up the names of your fields and tables before it gets too late. They are quite messy!
select mt. mshiptype_name, ts. timeslot_name, tt. timetable_Name
from membertopaymentoption mtp
inner join payment p on mtp. paymopt_Id = p.paymopt_Id
inner join mshiptypes mt on p.mshiptype_id = m.mshiptype_id
inner join timetables tt on mt.timetable_id = tt. timetable_id
inner join timeslottotimetables tstt on tt timetable_id = tstt. timetable_id
inner join timeslots ts on tstt. timeslot_id = ts. timetable_id
where mtp. member_Id = #memID //will be provided
select
mshiptype_name,
timeslot_name,
timetable_name
from
paymentoption
natural join membertopaymentoption
natural join mshiptypes
natural join timetables
natural join timeslottotimetables
natural join timeslots
where
member_Id = 1

Need help with SQL query

Current query
SELECT *
FROM employee AS E
INNER JOIN credential AS C ON (C.id = E.credentialId)
LEFT JOIN person AS P ON (C.personId = P.id)
I want to modify this query so that it I just SELECT the employees/credentials which have both loginroles 1 and 2 (loginrole.id).
Relevant tables
loginrole
id
name
credential_has_loginrole
id
credentialId
loginroleId
You can join a subquery, which will return the credential Id's that have both login roles.
SELECT E.*, C.*, P.*
FROM employee AS E
INNER JOIN (
SELECT credentialId
FROM credential_has_loginrole
WHERE loginroleId IN (1,2)
GROUP BY credentialId
HAVING COUNT(DISTINCT loginroleId) = 2
) g ON E.credentialId = g.credentialId
INNER JOIN credential AS C ON (C.id = E.credentialId)
LEFT JOIN person AS P ON (C.personId = P.id)
Update: As per comments, to find employees with either or:
SELECT E.*, C.*, P.*
FROM employee AS E
INNER JOIN (
SELECT credentialId
FROM credential_has_loginrole
WHERE loginroleId IN (1,2)
GROUP BY credentialId
) g ON E.credentialId = g.credentialId
INNER JOIN credential AS C ON (C.id = E.credentialId)
LEFT JOIN person AS P ON (C.personId = P.id)
Alternatively, you can use a JOIN together with DISTINCT:
SELECT DISTINCT E.*, C.*, P.*
FROM employee AS E
INNER JOIN credential AS C ON (C.id = E.credentialId)
INNER JOIN credential_has_loginrole chr
ON E.credentialId = chr.credentialId
AND chr.loginroleId IN (1,2)
LEFT JOIN person AS P ON (C.personId = P.id)
The Scrum Meister's answer is correct. You can alternatively use 2 join trees:
SELECT *
FROM employee AS E
INNER JOIN credential AS c
INNER JOIN credential_has_loginrole chl0 ON (c0.id=chl0.credentialId AND chl0.loginroleId=1)
INNER JOIN credential_has_loginrole chl1 ON (c0.id=chl1.credentialId AND chl1.loginroleId=2)
ON (c.id = E.credentialId)