How to join 4 tables with mysql - 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

Related

Select the first record of another table inside a select - MYSQL

I´m trying to make a query listing all clients, and also get the last comment and
the date of that comment inside the table of history_client inside a single query for it to be listed.
select a.id_client,a.name,a.lastname,(select b.date_created,b.comentary
from history_of_client b where a.id_client = b.id_client_asociate) from clients_main_table
You could use an inner join on max(date_created) for id_client on history table and join
SELECT a.id_client,a.name,a.lastname, h.commentary
FROM clients_main_table a
INNER join (
select b.id_client_asociate, max(b.date_created) max_date
from history_of_client
group by b.id_client_asociate ) t on t.id_client_asociate = a.id_client
INNER JOIN history_of_client h on h.id_client_asociate = t.id_client_asociate
and h.date_created = t.max_date
Use the LEFT JOIN and INNER join to get your desired result set.
select a.id_client,
a.name,
a.lastname,
hc.date_created,
hc.comentary
from clients_main_table c
left join (select id_client_asociate,max(date_created) dt from history_of_client group by id_client_asociate) h
on (c.id_client = b.id_client_asociate)
inner join history_of_client hc
on (hc.id_client_asociate = b.id_client_asociate and hc.date_created = h.date_created)

How to Left Join with Inner Join

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

Left Outer Join Subquery

I am trying to do a left outer join to a subquery, is that possible?
Can I do something like this?:
##this is this weeks targets
select * from targets t
inner join streams s on s.id = t.stream_id
where t.week_no =WEEKOFYEAR(NOW())
left outer join
(
###############This is records selected so far this week
select p.brand_id, p.part_product_family, sum(r.best) from records r
inner join products p on p.id = r.product_id
left outer join streams s on s.body = p.brand_id and s.stream = p.part_product_family
where WEEKOFYEAR(r.date_selected) =WEEKOFYEAR(NOW())
group by p.brand_id, p.part_product_family;
) sq_2
on s.stream = sq_2.part_product_family
This is working:
##this is this weeks targets
select * from targets t
inner join streams s on s.id = t.stream_id
left outer join
(
###############This is records selected so far this week
select p.brand_id, p.part_product_family, sum(r.best) from records r
inner join products p on p.id = r.product_id
left outer join streams s on s.body = p.brand_id and s.stream = p.part_product_family
where WEEKOFYEAR(r.date_selected) =WEEKOFYEAR(NOW()) and YEAR(r.date_selected) = YEAR(now())
group by p.brand_id, p.part_product_family
) sq_2
on s.body = sq_2.brand_id and s.stream = sq_2.part_product_family

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.

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)