How can i merge joins? - mysql

I have the following query which works but i would like to improve (performance wise):
.sentence_id and .project_id are indexes.
My goal now is to try to merge the 2 joins on the same tables into a single one (if possible)
How can i do that ?
SELECT rs.project_id,
ms.id AS raw_sentence_id,
rs.sentence AS raw_sentence_text,
rs.sentence_id AS raw_sentence_text_id,
rst.tokens AS tokenization_information,
ns.sentence_id AS normalized_sentence_id,
ns.sentence AS normalized_sentence_text,
nst.token_indices
FROM manual_sentences ms
JOIN sentences rs ON (ms.original_sentence_id = rs.sentence_id AND rs.project_id = 623483)
LEFT JOIN sentence_tokens rst ON (ms.original_sentence_id = rst.sentence_id AND rst.project_id = 623483)
JOIN sentences ns ON (ms.sentence_id = ns.sentence_id AND ns.project_id = 623483)
LEFT JOIN sentence_tokens nst ON (ms.sentence_id = nst.sentence_id AND nst.project_id = 623483)
WHERE ms.project_id = 623483

You should be able to do that using a conjunction:
SELECT rs.project_id,
ms.id AS raw_sentence_id,
rs.sentence AS raw_sentence_text,
rs.sentence_id AS raw_sentence_text_id,
rst.tokens AS tokenization_information,
ns.sentence_id AS normalized_sentence_id,
ns.sentence AS normalized_sentence_text,
nst.token_indices
FROM manual_sentences ms
JOIN sentences rs ON (ms.original_sentence_id = rs.sentence_id AND rs.project_id = 623483)
LEFT JOIN sentence_tokens rst ON (ms.original_sentence_id = rst.sentence_id AND ms.sentence_id = rst.sentence_id AND rst.project_id = 623483)
JOIN sentences ns ON (ms.sentence_id = ns.sentence_id AND ns.project_id = 623483)
WHERE ms.project_id = 623483

Related

Left join is not working on codeigniter

I am new in code igniter. I am trying to execute delete query using joining multiple tables, but I am getting error in query.
Here is my query code.
$this->db->from('order');
$this->db->join('item_order', 'item_order.order_id = order.order_id','left');
$this->db->join('product', 'product.product_number = item_order.item_number','left');
$this->db->join('product_to_image', 'product_to_image.p_id = product.products_id','left');
$this->db->join('product_to_dropbox', 'product_to_dropbox.products_id = product.products_id','left');
$this->db->where('order.user_name', $ebay_user_name);
$this->db->where('order.user_id', $user_id);
$this->db->delete('order');
When using Codeigniter you can not perform a DELETE with Join. see here and here.
You need to write a natural SQL. See link 1:
$sql = "DELETE o FROM order as o
LEFT JOIN item_order ON item_order.order_id = order.order_id
LEFT JOIN product ON product.product_number = item_order.item_number
LEFT JOIN product_to_image ON product_to_image.p_id = product.products_id
LEFT JOIN product_to_dropbox ON product_to_dropbox.products_id = product.products_id
WHERE order.user_name = ? and order.user_id = ?";
$this->db->query($sql, array($ebay_user_name, $user_id));
OR try with backticks `. But I'm not sure whether or not escaping them:
$sql = "DELETE o FROM `order` as o
LEFT JOIN `item_order` ON item_order.order_id = order.order_id
LEFT JOIN `product` ON product.product_number = item_order.item_number
LEFT JOIN `product_to_image` ON product_to_image.p_id = product.products_id
LEFT JOIN `product_to_dropbox` ON product_to_dropbox.products_id = product.products_id
WHERE order.user_name = ? and order.user_id = ?";
$this->db->query($sql, array($ebay_user_name, $user_id));

Not unique table/alias in mysql while joining from different database

I get the error [Err] 1066 - Not unique table/alias: 'vtiger_leadscf'
UPDATE vtigerdb.vtiger_leadscf
JOIN vtiger_new.vtiger_leaddetails ON vtiger_new.vtiger_leadscf.leadid = vtiger_new.vtiger_leaddetails.leadid
JOIN vtiger_new.vtiger_leadaddress ON vtiger_new.vtiger_leadaddress.leadaddressid = vtiger_new.vtiger_leadscf.leadid
JOIN vtiger_new.vtiger_crmentity ON vtiger_new.vtiger_crmentity.crmid = vtiger_new.vtiger_leadscf.leadid
JOIN vtiger_new.vtiger_users ON vtiger_new.vtiger_users.id = vtiger_new.vtiger_crmentity.smcreatorid
JOIN vtigerdb.vtiger_leadscf ON vtigerdb.vtiger_leadscf.leadid = vtiger_new.vtiger_leadscf.leadid
SET vtigerdb.vtiger_leadscf.cf_953 = CONCAT(vtiger_new.vtiger_users.first_name,' ',vtiger_new.vtiger_users.last_name)
WHERE vtigerdb.vtiger_leadscf.leadid = vtiger_new.vtiger_leadscf.leadid
AND cf_953 = ""
can't figure out whats wrong with it.
Last join and update reference the same table.
Use JOIN table AS other_name to avoid this problem.
Here is the corrected query.
Plus I think you meant vtiger_new on the last join and not vtigerdb as you wrote.
UPDATE vtigerdb.vtiger_leadscf
JOIN vtiger_new.vtiger_leaddetails ON vtiger_new.vtiger_leadscf.leadid = vtiger_new.vtiger_leaddetails.leadid
JOIN vtiger_new.vtiger_leadaddress ON vtiger_new.vtiger_leadaddress.leadaddressid = vtiger_new.vtiger_leadscf.leadid
JOIN vtiger_new.vtiger_crmentity ON vtiger_new.vtiger_crmentity.crmid = vtiger_new.vtiger_leadscf.leadid
JOIN vtiger_new.vtiger_users ON vtiger_new.vtiger_users.id = vtiger_new.vtiger_crmentity.smcreatorid
JOIN vtiger_new.vtiger_leadscf AS vlead ON vtigerdb.vtiger_leadscf.leadid = vlead.leadid
SET vtigerdb.vtiger_leadscf.cf_953 = CONCAT(vtiger_new.vtiger_users.first_name,' ',vtiger_new.vtiger_users.last_name)
WHERE vtigerdb.vtiger_leadscf.leadid = vlead.leadid
AND cf_953 = ""

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))

Getting unique values with SUM and JOIN

I'm trying to get the total of calc.transport
Table 3_product_folder contains duplicate values (column 'folder_id'), how can I prevent the from messing up the SUM?
I have tried DISTINCT with no succes.
Any suggestions?
SELECT
SUM(calc.transport) AS transport
FROM 0_calculatie_id AS calc
LEFT JOIN 0_calculatie_inh_id AS id
ON id.calculatie_id = calc.id
LEFT JOIN 3_product_folder AS fld_id
ON fld_id.product_id = id.id
LEFT JOIN 4_folder_dossier AS fld
ON fld.product_folder_id = fld_id.folder_id
LEFT JOIN 10_factuur_inh AS fac_inh
ON fac_inh.folder_id = fld.id
LEFT JOIN 9_factuur_id AS fac
ON fac.id = fac_inh.factuur_id
WHERE YEAR(fac.datum_verstuurd) = ".$row['jaar']." AND MONTH(fac.datum_verstuurd) = ".$row_mth2['maand']."
I have tried this nested query but that not all items are calculated then:
SELECT
SUM(temp.transport) AS transport
FROM
(SELECT DISTINCT
calc.transport,
fld_id.folder_id
FROM 0_calculatie_id AS calc
LEFT JOIN 0_calculatie_inh_id AS id
ON id.calculatie_id = calc.id
LEFT JOIN 3_product_folder AS fld_id
ON fld_id.product_id = id.id
LEFT JOIN 4_folder_dossier AS fld
ON fld.product_folder_id = fld_id.folder_id
LEFT JOIN 10_factuur_inh AS fac_inh
ON fac_inh.folder_id = fld.id
LEFT JOIN 9_factuur_id AS fac
ON fac.id = fac_inh.factuur_id
WHERE YEAR(fac.datum_verstuurd) = 2012 AND MONTH(fac.datum_verstuurd) = 7) AS temp
what the structure of the table?
you haven't grouped the SQL statement:
WHERE YEAR(fac.datum_verstuurd) = ".$row['jaar']." AND MONTH(fac.datum_verstuurd) = ".$row_mth2['maand']."
GROUP BY fld_id.product_id

Linq to SQL with more conditiones on one join

I'm new to Linq to SQL and I'm trying to transform this SQL into Linq. Could you please help me out.
SELECT *
FROM [dbo].[tblTest]
INNER JOIN [dbo].[tblStationTest] ON [tblTest].[id] = [tblStationTest].[Test_id]
INNER JOIN [dbo].[tblTestType] ON [tblTest].[TestType_id] = [tblTestType].[id]
LEFT OUTER JOIN [dbo].[tblTestOrder] ON [tblTest].[id] = [tblTestOrder].[Test_id]
AND ([tblTestOrder].[TestOrderList_id] = 1)
WHERE ([Station_id] = 1)
What is causing me problem is this condition AND ([TestOrderList_id] = 1)
This condition can't be in Where clase because it will cancel the effect of Left Join
Thanks kurin
you can try something like
from test in db.tblTest
join stationTest in db.tblStationTest on test.id equals stationTest.Test_id
join testType in db.tblTestType on test.TestType_id equals testType.id
join testOrder in db.tblTestOrder on new{Key1 = test.id, Key2= 1} equals new{Key1 = testOrder.Test_id, Key2 = testOrder.TestOrderList_id} into tempOrders
from t in tempOrders.DefaultIfEmpty()
select new{test.Test_id, testType.something, t.somethingelse}