Join on three tables not showing all records - mysql

I have the code below:
SELECT
*
FROM
produto_unidades
join produto_notas on produto_notas.id = produto_unidades.produtoNota_id
join produto_licitacoes on produto_licitacoes.id = produto_notas.produtoLicitacoes_id
where produto_unidades.unidade_id = 2
This code work correctly, but I need to get ALL records of the produto_licitacoes.
Any idea?

Use left join instead of inner join. Make produto_licitacoes table as your left-most table; this would ensure that all the rows of produto_licitacoes table do appear in the result.
When using Left Join, you will need to shift the where conditions on the tables (except leftmost one) to the join on condition.
Try the following:
SELECT
*
FROM
produto_licitacoes
left join produto_notas
on produto_licitacoes.id = produto_notas.produtoLicitacoes_id
left join produto_unidades
on produto_notas.id = produto_unidades.produtoNota_id and
produto_unidades.unidade_id = 2

Two RIGHT JOIN will do:
SELECT
*
FROM
produto_unidades
right join produto_notas on produto_notas.id = produto_unidades.produtoNota_id
right join produto_licitacoes on produto_licitacoes.id = produto_notas.produtoLicitacoes_id
and produto_unidades.unidade_id = 2
However, to me it's a lot easier to read using LEFT JOIN syntax. Please note the tables show up in inverted order:
select *
from produto_licitacoes l
left join produto_notas n on n.produtoLicitacoes_id = l.id
left join produto_unidades u on u.produtoNota_id = n.id
and u.unidade_id = 2

Related

Problem when using full join but not using left join. Why?

When I use a left join on different databases, it works but not when I use inner join. Why ?
SELECT tkblue_tklabel_dev_data.EmailContent.*, tkblue_tklabel_dev_archdata.EmailTracking.*
FROM tkblue_tklabel_dev_data.EmailContent
FULL JOIN tkblue_tklabel_dev_archdata.EmailTracking ON tkblue_tklabel_dev_archdata.EmailTracking.idEmailTracking = tkblue_tklabel_dev_data.EmailContent.idEmailTracking
Unknown table 'tkblue_tklabel_dev_data.EmailContent'
But when using
SELECT tkblue_tklabel_dev_data.EmailContent.*, tkblue_tklabel_dev_archdata.EmailTracking.*
FROM tkblue_tklabel_dev_data.EmailContent
LEFT JOIN tkblue_tklabel_dev_archdata.EmailTracking ON tkblue_tklabel_dev_archdata.EmailTracking.idEmailTracking =
tkblue_tklabel_dev_data.EmailContent.idEmailTracking
I have not this error message, but I can only have the results of the left table. Or, I wish all the results like an full join.
Full join don't exists in mysql but you can produce the same result using both left join and right join in UNION
SELECT tkblue_tklabel_dev_data.EmailContent.*
, tkblue_tklabel_dev_archdata.EmailTracking.*
FROM tkblue_tklabel_dev_data.EmailContent
LEFT JOIN tkblue_tklabel_dev_archdata.EmailTracking
ON tkblue_tklabel_dev_archdata.EmailTracking.idEmailTracking = tkblue_tklabel_dev_data.EmailContent.idEmailTracking
UNION
SELECT tkblue_tklabel_dev_data.EmailContent.*
, tkblue_tklabel_dev_archdata.EmailTracking.*
FROM tkblue_tklabel_dev_data.EmailContent
RIGHT JOIN tkblue_tklabel_dev_archdata.EmailTracking
ON tkblue_tklabel_dev_archdata.EmailTracking.idEmailTracking = tkblue_tklabel_dev_data.EmailContent.idEmailTracking

How to make LEFT OUTER JOIN except some colums?

I have 3 tables:
First "placement"
Second "user_info"
Third "user_placements"
I want to get all placement data with user infos,
How to do it?
I tried this, but result it not what I expected:
SELECT *, user_placements.id AS user_placements_id, placement.id AS placement_id
FROM placement
LEFT OUTER JOIN user_placements ON placement.id = user_placements.id_placement
you need to one more join with user info
SELECT placement.*,user_info.id as user_info_id,user_info.name as user_name,user_info.mobile as user_mobile
FROM placement LEFT OUTER JOIN user_placements ON placement.id = user_placements.id_placement
LEFT OUTER JOIN user_info ON user_info.id = user_placements.id_user
You are missing the second join:
SELECT *
FROM placement AS p
JOIN user_placements AS up ON p.id = up.id_placement
JOIN user_info AS u ON up.id_user = u.id
Replace the wildcard with the data you want.
You will of course get duplicated data with this query.

Inner Join only returning values if match is in all four tables

I have the following INNER JOIN statement and It is only returning results if all four tables have a match for the order number in them.
I need it to include every result in the main table KC_Orders regardless of the equivalent contents of each INNER JOIN tables in the $sql
I understand that this is the point of the INNER JOIN but I need it do something else.
$sql = "SELECT *
FROM `KC_Orders`
INNER JOIN `KC_Payments`
ON KC_Orders.orderNumber = KC_Payments.orderNumber
INNER JOIN `KC_OrderStatus`
ON KC_Orders.orderNumber = KC_OrderStatus.orderNumber
INNER JOIN `KC_Statuses`
ON KC_OrderStatus.statusID = KC_Statuses.statusID";
$AllOrders = $db->query($sql);
Use left outer joins
SELECT *
FROM
`KC_Orders`
LEFT JOIN `KC_Payments`
ON KC_Orders.orderNumber = KC_Payments.orderNumber
LEFT JOIN `KC_OrderStatus`
ON KC_Orders.orderNumber = KC_OrderStatus.orderNumber
LEFT JOIN `KC_Statuses`
ON KC_OrderStatus.statusID = KC_Statuses.statusID
If there is always a status available, you can keep the inner join for the KC_Statuses table
SELECT *
FROM
A
LEFT JOIN B
ON A.id = B.id
... means that all the records from A will be returned and only the records from B that match a record from A. Records from A are returned even when there is no matching record in B.
It sounds like you want an OUTER JOIN rather than an INNER JOIN.
If you want all rows from the KC_Orders table, then put that table first in the FROM clause, and use a LEFT JOIN on the other tables. (The OUTER keyword is not required.) This will return all rows from the KC_Orders table, even if no matching row is found in the other tables. NULL values will be returned in place of value from "missing" rows.
SELECT *
FROM `KC_Orders`
LEFT
JOIN `KC_Payments`
ON KC_Orders.orderNumber = KC_Payments.orderNumber
LEFT
JOIN `KC_OrderStatus`
ON KC_Orders.orderNumber = KC_OrderStatus.orderNumber
LEFT
JOIN `KC_Statuses`
ON KC_OrderStatus.statusID = KC_Statuses.statusID

LEFT OUTER JOIN query not returning expected rows

My aim is to do exactly what a LEFT OUTER JOIN intends to do using the 4th venn diagram: SQL Diagrams:
My query isn't returning any values at all, where in fact, it should be returning all within the Consultant_Memberships minus the one that is stored within Consultant_Memberships_Lists.
Please see the SQL Fiddle for an easier understanding:
SELECT *
FROM consultant_memberships
LEFT OUTER JOIN consultant_memberships_list
ON consultant_memberships.`id` =
consultant_memberships_list.membership_id
WHERE consultant_memberships_list.consultant_id = $id
AND consultant_memberships_list.membership_id IS NULL
The query is using '5' as an ID for demonstration purposes to try and pick out the correct rows.
You current query is basically doing an INNER JOIN because of the consultant_id = 5 on the WHERE clause. I believe you actually want to use:
SELECT *
FROM consultant_memberships m
LEFT OUTER JOIN consultant_memberships_list l
ON m.`id` = l.membership_id
AND l.consultant_id = 5
WHERE l.membership_id IS NULL;
See SQL Fiddle with Demo
Use
SELECT *
FROM consultant_memberships
LEFT Outer JOIN consultant_memberships_list
ON consultant_memberships_list.membership_id = consultant_memberships.`id`
and consultant_memberships_list.consultant_id = 5
where consultant_memberships_list.membership_id IS NULL;
The Where clause used before in your query "consultant_memberships_list.consultant_id = 5 " was neglecting the left outer join.

MySQL Select ALL from Left Join

This query does not work. I want all the results from a LEFT JOIN where something is something. This is my exact code:
SELECT * FROM `swarovski_zones` WHERE `siteid`='200'
LEFT JOIN `trafficviews` ON `swarovski`.`id`=`trafficviews`.`adid`
swarovski_zones table is siteid 200
trafficviews table is adid 200
The 200 is the linking variable between the tables. I want everything from both tables where the ID is 200.
The query doesn't work because the syntax is incorrect. It should be:
select
from
join
on
where
group by
having
order by
limit
Giving you:
select *
from `swarovski_zones`
left join `trafficviews`
on `swarovski`.`id` = `trafficviews`.`adid`
where `siteid` = '200'
Also is siteid meant to be a string and not an integer?
I'm probably going to regret providing the list above...
Limit! I forgot Limit; the full syntax list is here
The problem here is that elements in your right table (trafficviews) might not have a correspondant row in your left table (swarovski_zones). So the left join will get all elements from the left and might leave out some elements from the right.
To solve this, you need an outer join. Your problem is that MySQL does not support outer joins :) This is solved in the following general way:
SELECT * FROM a LEFT JOIN b ON a.id = b.id
UNION ALL
SELECT * FROM a RIGHT JOIN b ON a.id = b.id WHERE a.id IS NULL;
Applied to your question this should be something like:
SELECT * FROM swarovski_zones s
LEFT JOIN trafficviews ON s.id = t.adid
UNION ALL
SELECT * FROM swarovski_zones s
RIGHT JOIN trafficviews ON s.id = t.adid WHERE s.id IS NULL
WHERE s.siteid = 200 or t.adid = 200
Give it a try.
User full outer join
SELECT * FROM `swarovski_zones` WHERE `siteid`='200'
FULL OUTER JOIN `trafficviews` ON `swarovski`.`id`=`trafficviews`.`adid`