Why they use left join instead of inner join in this code - mysql

I'm newbie in sql... This query seems to run completely fine with inner join, and then why the author still chose left join ?
SELECT *
FROM {$wpdb->posts} notices
LEFT JOIN {$wpdb->postmeta} instances
ON ( notices.ID = instances.post_id AND instances.meta_key = 'mycred_email_instance' )
LEFT JOIN {$wpdb->postmeta} pointtype
ON ( notices.ID = pointtype.post_id AND pointtype.meta_key = 'mycred_email_ctype' )
WHERE instances.meta_value = %s
AND pointtype.meta_value IN (%s,'all')
AND notices.post_type = 'mycred_email_notice'
AND notices.post_status = 'publish'
Thanks in advance !

Related

WHERE clause on Multiple type of Join query

I'm having problems with a MySQL Query. I have read a lot of the currently answered threads, following a lot of examples but I have not been able to solve my trouble so I come to you for help. Thanks in advance.
I have this query:
SELECT ventas.*,
clientes.nombre AS CLIENT_NOMBRE,
clientes.telefono AS TELEFONO,
users.nombre AS USERNAME,
canales_ventas.nombre AS CAN_VENTA,
estados_venta.nombre AS ESTADOS,
metodos_pago.nombre AS MET_PAGO,
canales_entrega.nombre AS CAN_ENTREGA,
canales_entrega.categoria AS CAN_ENTREGA_CAT,
COALESCE(perc.qty,0) AS DESC_PERCENT,
COALESCE(fix.qty,0) AS DESC_FIXED,
COALESCE(SUM(ventas_productos.vp_cantidad*ventas_productos.vp_precio),0) AS Total_Value
FROM ventas
JOIN clientes ON clientes.id = ventas.cliente_id
JOIN users ON users.id = ventas.vendedor_id
LEFT OUTER JOIN canales_ventas ON canales_ventas.id = ventas.canal_venta_id
LEFT OUTER JOIN estados_venta ON estados_venta.id = ventas.estado_actual
LEFT OUTER JOIN metodos_pago ON metodos_pago.id = ventas.metodo_pago
LEFT OUTER JOIN canales_entrega ON canales_entrega.id = ventas.metodo_entrega
LEFT OUTER JOIN ventas_descuentos perc ON perc.orden_id = ventas.id AND perc.tipo = 1
LEFT OUTER JOIN ventas_descuentos fix ON fix.orden_id = ventas.id AND fix.tipo = 2
LEFT JOIN ventas_productos ON ventas_productos.vp_orden_id = ventas.id GROUP BY ventas.id
But I need that all the results match ventas.estado_actual = 7
I'd appreciate a lot the help. Thanks!
EDIT1:
I have tried Using WHERE in these ways:
After the last Join:
SELECT ventas.*,
clientes.nombre AS CLIENT_NOMBRE,
clientes.telefono AS TELEFONO,
users.nombre AS USERNAME,
canales_ventas.nombre AS CAN_VENTA,
estados_venta.nombre AS ESTADOS,
metodos_pago.nombre AS MET_PAGO,
canales_entrega.nombre AS CAN_ENTREGA,
canales_entrega.categoria AS CAN_ENTREGA_CAT,
COALESCE(perc.qty,0) AS DESC_PERCENT,
COALESCE(fix.qty,0) AS DESC_FIXED,
COALESCE(SUM(ventas_productos.vp_cantidad*ventas_productos.vp_precio),0) AS Total_Value
FROM ventas
JOIN clientes ON clientes.id = ventas.cliente_id
JOIN users ON users.id = ventas.vendedor_id
LEFT OUTER JOIN canales_ventas ON canales_ventas.id = ventas.canal_venta_id
LEFT OUTER JOIN estados_venta ON estados_venta.id = ventas.estado_actual
LEFT OUTER JOIN metodos_pago ON metodos_pago.id = ventas.metodo_pago
LEFT OUTER JOIN canales_entrega ON canales_entrega.id = ventas.metodo_entrega
LEFT OUTER JOIN ventas_descuentos perc ON perc.orden_id = ventas.id AND perc.tipo = 1
LEFT OUTER JOIN ventas_descuentos fix ON fix.orden_id = ventas.id AND fix.tipo = 2
LEFT JOIN ventas_productos ON ventas_productos.vp_orden_id = ventas.id GROUP BY ventas.id
WHERE ventas.estado_actual = 7
ERROR #1064 - Something is wrong in your syntax 'LIMIT 0, 25' on line 23
In the From Clause:
SELECT ventas.*,
clientes.nombre AS CLIENT_NOMBRE,
clientes.telefono AS TELEFONO,
users.nombre AS USERNAME,
canales_ventas.nombre AS CAN_VENTA,
estados_venta.nombre AS ESTADOS,
metodos_pago.nombre AS MET_PAGO,
canales_entrega.nombre AS CAN_ENTREGA,
canales_entrega.categoria AS CAN_ENTREGA_CAT,
COALESCE(perc.qty,0) AS DESC_PERCENT,
COALESCE(fix.qty,0) AS DESC_FIXED,
COALESCE(SUM(ventas_productos.vp_cantidad*ventas_productos.vp_precio),0) AS Total_Value
FROM ventas WHERE ventas.estado_actual = 7
JOIN clientes ON clientes.id = ventas.cliente_id
JOIN users ON users.id = ventas.vendedor_id
LEFT OUTER JOIN canales_ventas ON canales_ventas.id = ventas.canal_venta_id
LEFT OUTER JOIN estados_venta ON estados_venta.id = ventas.estado_actual
LEFT OUTER JOIN metodos_pago ON metodos_pago.id = ventas.metodo_pago
LEFT OUTER JOIN canales_entrega ON canales_entrega.id = ventas.metodo_entrega
LEFT OUTER JOIN ventas_descuentos perc ON perc.orden_id = ventas.id AND perc.tipo = 1
LEFT OUTER JOIN ventas_descuentos fix ON fix.orden_id = ventas.id AND fix.tipo = 2
LEFT JOIN ventas_productos ON ventas_productos.vp_orden_id = ventas.id GROUP BY ventas.id
ERROR - #1064 Again the same error
where clause must be before group by
WHERE ventas.estado_actual = 7 GROUP BY ventas.id

mysql where not in to left outer join

I have the following query and would like to convert it to using a left outer join instead of a not in to see if it would run faster that way. It's currently taking this query about 40 seconds to run on our database. I'm not familiar enough with using outer joins for this type of thing to convert it myself.
select
c.contact_id as contact_id,
c.orgid as organization_id,
c.first_name as first_name,
c.last_name as last_name,
a.address_state as state
from cnx_contact as c
inner join cnx_address as a on c.home_address_uid = a.address_uid
where a.address_state = 'OH'
and (c.orgid = 45 or c.orgid = 55)
and c.contact_id NOT IN (
select pc.contact_id
from cnx_contact as c
inner join cnx_address as a on c.home_address_uid = a.address_uid
inner join cnx_contact_group_participant as gp on c.contact_id = gp.contact_id
inner join cnx_contact_participant_role as cr on gp.participant_role_uid = cr.participant_role_uid
inner join cnx_contact_group as cg on gp.group_uid = cg.group_uid
inner join cnx_contact_group_participant as pgp on cg.primary_participant_uid = pgp.participant_uid
inner join cnx_contact as pc on pgp.contact_id = pc.contact_id
where (c.orgid = 45 or c.orgid = 55)
and cr.name = 'Applicant'
);
select
c.columns
from cnx_contact as c
inner join cnx_address as a on c.home_address_uid = a.address_uid
LEFT JOIN
(Subquery goes here) x
ON x.contact _id = c.contact_id
where a.participant_state = 'OH'
and c.orgid IN(45,55)
and x.contact_id IS NULL;

slow query with joins

Please am having difficulty in optimizing this query. What am trying to achieve is to join about 8 tables, of which only about 3 of the tables contains large data (1.5m records). This query returns expected records but is taking 1min to run which is bad.
I know it can be optimized to perform far better, pls i need assistance from you experts. I have index on the fields used for join already.
SELECT topic_id,
topic_title,
unit_name_abbrev,
sch_name_abbrev,
picture_small_url AS thumbnail,
profile_pix_upload_path,
first_name,
last_name,
topic_poster,
topic_replies,
topic_views,
topic_last_post_time AS topic_post_time,
sch_sub_forum_id
FROM (_sch_forum_topics
INNER JOIN _users
ON ( _users.userid = _sch_forum_topics.topic_poster )
INNER JOIN _profile
ON _profile.userid = _users.userid
INNER JOIN _class
ON _users.classid = _class.classid
INNER JOIN _level
ON _class.level_id = _level.id
INNER JOIN _unit
ON _class.unitid = _unit.unitid
INNER JOIN _department
ON _unit.deptid = _department.deptid
INNER JOIN _faculty
ON _department.facid = _faculty.facid
INNER JOIN _university
ON _faculty.schid = _university.schid)
WHERE _sch_forum_topics.sch_sub_forum_id = 4
ORDER BY _sch_forum_topics.topic_last_post_time DESC
LIMIT 0, 15
Try to filter before making JOIN's.
SELECT topic_id,
topic_title,
unit_name_abbrev,
sch_name_abbrev,
picture_small_url AS thumbnail,
profile_pix_upload_path,
first_name,
last_name,
topic_poster,
topic_replies,
topic_views,
topic_last_post_time AS topic_post_time,
sch_sub_forum_id
FROM
( select * FROM sch_forum_topics WHERE sch_sub_forum_id = 4
ORDER BY topic_last_post_time DESC
LIMIT 0, 15 ) main
INNER JOIN _users
ON ( _users.userid = main.topic_poster )
INNER JOIN _profile
ON _profile.userid = _users.userid
INNER JOIN _class
ON _users.classid = _class.classid
INNER JOIN _level
ON _class.level_id = _level.id
INNER JOIN _unit
ON _class.unitid = _unit.unitid
INNER JOIN _department
ON _unit.deptid = _department.deptid
INNER JOIN _faculty
ON _department.facid = _faculty.facid
INNER JOIN _university
ON _faculty.schid = _university.schid);

Speeding up MySQL Query inc subquery-join?

I've got the query below that's pulling data from a number of tables to create an update:
UPDATE en_inter.subscribers_data AS sd
inner join en_inter.list_subscribers AS ls on sd.subscriberid = ls.subscriberid
LEFT JOIN (
SELECT pd1.email_address,COUNT(pd1.email_address) AS NumDowns
FROM email.papr_down pd1
INNER JOIN email.papr_data pd2 on pd1.paper_id = pd2.id
INNER JOIN email.papr_subj ps on ps.id = pd2.subject
INNER JOIN email.papr_exam pe on pe.id = pd2.exam
INNER JOIN email.papr_levl pl on pl.id = pd2.level
WHERE pd2.exam = 1
and pd2.level = 4
GROUP BY email_address
) AS downs ON downs.email_address = ls.emailaddress
SET sd.data = ifnull(downs.NumDowns,1)
WHERE sd.fieldid = 33;
It works fine but when there are plenty of records in papr_down then it takes ages to process. Any ideas about how it can be optimized?
What I think is the join between the emailAddress is the issue here, you can try out with the join with the Id's.
If you provide us the screen shot of the below query ::
EXPLAIN Select * from
en_inter.subscribers_data AS sd
inner join en_inter.list_subscribers AS ls on sd.subscriberid = ls.subscriberid
LEFT JOIN (
SELECT pd1.email_address,COUNT(pd1.email_address) AS NumDowns
FROM email.papr_down pd1
INNER JOIN email.papr_data pd2 on pd1.paper_id = pd2.id
INNER JOIN email.papr_subj ps on ps.id = pd2.subject
INNER JOIN email.papr_exam pe on pe.id = pd2.exam
INNER JOIN email.papr_levl pl on pl.id = pd2.level
WHERE pd2.exam = 1
and pd2.level = 4
GROUP BY email_address
) AS downs ON downs.email_address = ls.emailaddress
WHERE sd.fieldid = 33
As I know we should use joins only for the columns which are preset in SELECT clause and for other joins we should implement using WHERE clause
Please try following query:
UPDATE en_inter.subscribers_data AS sd
inner join en_inter.list_subscribers AS ls
on sd.subscriberid = ls.subscriberid
LEFT JOIN (
SELECT pd1.email_address,COUNT(pd1.email_address) AS NumDowns
FROM email.papr_down AS pd1
INNER JOIN email.papr_data AS pd2 on pd1.paper_id = pd2.id
WHERE
email.papr_exam.id in (select exam from email.papr_data where exam = 1)
AND
email.papr_levl.id in (select level from email.papr_data where level = 4 )
AND
email.papr_subj.id in (select subject from email.papr_data)
GROUP BY email_address
) AS downs ON downs.email_address = ls.emailaddress
SET sd.data = ifnull(downs.NumDowns,1)
WHERE sd.fieldid = 33;
I can not execute this at my machine since i don't have the schema

IF/ELSE LEFT JOIN

I need to do a LEFT JOIN with IF/ELSE, this is my query:
IF (M.idArtVar=null,
LEFT JOIN ArtMaga G
ON (G.idMagazzino = V.idMagazzino AND G.idArticolo = M.idArticolo),
LEFT JOIN ArtMaga G
ON (G.idMagazzino = V.idMagazzino AND G.idArticolo = M.idArticolo AND
G.idArtVar = M.idArtVar)
)
But it doesn't work.
I also tried like this:
LEFT JOIN ArtMaga AM
ON IF(M.idArtVar IS NULL,
(AM.idMagazzino = TM.idMagazzino AND AM.idArticolo = A.idArticoli),
(AM.idMagazzino = TM.idMagazzino AND AM.idArtVar = M.idArtVar))
But this query is too slow.
How can I do?
Thanks.
EDIT: This is full query:
SELECT F.Codice AS "CodiceFornitore", F.RagioneSociale AS "RagioneSocialeFornitore", A.ArticoloFornitore, C.Descrizione AS CatDes, S.Descrizione AS Settore, U.Sigla AS Um, U2.Sigla AS Um2, A.Moltiplicatore AS Molt, A.Collo, TM.
dMagazzino, M.idArtVar, AM.Esistenza, AM.Disponibilita, AM.QtaImpegnata, AM.QtaOrdinata, TM.TipoSoggetto, TM.idSoggetto, ST.DataMovimento, MC.Codice, ST.Quantita, ST.Prezzo, ST.Sconti, M.idMagaRigMov
FROM MagaRigMov M
LEFT JOIN Articoli A ON A.idArticoli = M.idArticolo
LEFT JOIN UnMisura U ON U.idUnMisura = A.idUnMisura1
LEFT JOIN UnMisura U2 ON U2.idUnMisura = A.idUnMisura2
LEFT JOIN Iva I ON I.idIva = A.idIva
LEFT JOIN Settori S ON S.idSettori = A.idSettore
LEFT JOIN Fornitori F ON F.idFornitori = A.idFornitore
LEFT JOIN ArtCategorie C ON C.idArtCategorie = A.idArtCategoria
LEFT JOIN MagaTesMov TM ON TM.idMagaTesMov = M.idMagaTesMov
LEFT JOIN STORICO ST ON (ST.idSoggetto = TM.idSoggetto AND ST.TipoSoggetto = TM.TipoSoggetto AND ST.idArticolo = M.idArticolo)
LEFT JOIN MagaCausali MC ON MC.idMagaCausali = ST.idMagaCausale
LEFT JOIN ArtMaga AM ON IF(M.idArtVar IS NULL,(AM.idMagazzino = TM.idMagazzino AND AM.idArticolo = A.idArticoli),
(AM.idMagazzino = TM.idMagazzino AND AM.idArtVar = M.idArtVar))
This query is too slow.. but works..
You can't use an IF to make a conditional join. Because IF is not part of the SELECT syntax and even if it was (like CASE expressions) it wouldn't be allowed to be used like this. You can move the logic to the ON statement though:
LEFT JOIN ArtMaga G
ON (G.idMagazzino = V.idMagazzino AND G.idArticolo = M.idArticolo)
AND M.idArtVar IS NULL
OR (G.idMagazzino = V.idMagazzino AND G.idArticolo = M.idArticolo AND
G.idArtVar = M.idArtVar)
AND M.idArtVar IS NOT NULL
which can be simplified to:
LEFT JOIN ArtMaga G
ON (G.idMagazzino = V.idMagazzino AND G.idArticolo = M.idArticolo)
AND (M.idArtVar IS NULL OR G.idArtVar = M.idArtVar)
Also notice that you can't use equality to check if an expression is null.
M.idArtVar = null will never be true because NULL can never be equal to anything (not even to NULL). The way to check if an expression is null is with IS NULL.
Your second query, that words, is using the IF() function of MySQL and seems to be correct (although I see a difference in the code with the first query, the G.idArticolo = M.idArticolo condition has been removed from one part.)
Why a query is slow depends on many factors and using functions on the join conditions can be one of the many. Try the change I suggest above. If it still slow, you'll have to examine the execution plan and the available indexes on the tables.
Just put the condition in the on clause. If is not part of a SQL statement.
SELECT F.Codice AS "CodiceFornitore", F.RagioneSociale AS "RagioneSocialeFornitore",
A.ArticoloFornitore, C.Descrizione AS CatDes, S.Descrizione AS Settore, U.Sigla AS Um, U2.Sigla AS Um2, A.Moltiplicatore AS Molt, A.Collo, TM.
dMagazzino, M.idArtVar, AM.Esistenza, AM.Disponibilita, AM.QtaImpegnata, AM.QtaOrdinata, TM.TipoSoggetto, TM.idSoggetto, ST.DataMovimento, MC.Codice, ST.Quantita, ST.Prezzo, ST.Sconti, M.idMagaRigMov
FROM MagaRigMov M
LEFT JOIN Articoli A ON A.idArticoli = M.idArticolo
LEFT JOIN UnMisura U ON U.idUnMisura = A.idUnMisura1
LEFT JOIN UnMisura U2 ON U2.idUnMisura = A.idUnMisura2
LEFT JOIN Iva I ON I.idIva = A.idIva
LEFT JOIN Settori S ON S.idSettori = A.idSettore
LEFT JOIN Fornitori F ON F.idFornitori = A.idFornitore
LEFT JOIN ArtCategorie C ON C.idArtCategorie = A.idArtCategoria
LEFT JOIN MagaTesMov TM ON TM.idMagaTesMov = M.idMagaTesMov
LEFT JOIN STORICO ST ON (ST.idSoggetto = TM.idSoggetto AND ST.TipoSoggetto = TM.TipoSoggetto AND ST.idArticolo = M.idArticolo)
LEFT JOIN MagaCausali MC ON MC.idMagaCausali = ST.idMagaCausale
LEFT JOIN ArtMaga AM ON (AM.idMagazzino = TM.idMagazzino AND (m.idartVar is NULL and AM.idArtVar = M.idArtVar or AM.idArticolo = A.idArticoli))