Not unique table/alias on join - mysql

I intend to do an update based on join, but getting an error. What is missing?
update
vna.patients,
vna.patient_observations,
vna.studies,
vna.series,
vna.instances,
vna.sop_classes,
vna.files,
vna.modalities,
vna.issuers
join patient_observations on atients.patient_id=patient_observations.patient_id
join studies
on patient_observations.study_id=studies.study_id
AND studies.patient_id=patients.patient_id
join series
on series.study_id=studies.study_id
join instances
on instances.series_id=series.series_id
join sop_classes
on sop_classes.sop_class_id=instances.sop_class_id
join files
on files.instance_id=instances.instance_id
left join modalities
on modalities.modality_id=series.modality_id
left join issuers
on (patients.issuer_of_patient_identifier=issuers.issuer_id)
set PATIENT_NAME='AAPM'
WHERE PATIENT_IDENTIFIER='TG18-2002';
ERROR 1066 (42000): Not unique table/alias: 'patient_observations'

You don't need to specify table names again which appears in join part
UPDATE
vna.patients
JOIN patient_observations
ON patients.patient_id = patient_observations.patient_id
JOIN studies
ON patient_observations.study_id = studies.study_id
AND studies.patient_id = patients.patient_id
JOIN series
ON series.study_id = studies.study_id
JOIN instances
ON instances.series_id = series.series_id
JOIN sop_classes
ON sop_classes.sop_class_id = instances.sop_class_id
JOIN files
ON files.instance_id = instances.instance_id
LEFT JOIN modalities
ON modalities.modality_id = series.modality_id
LEFT JOIN issuers
ON (patients.issuer_of_patient_identifier = issuers.issuer_id)
SET PATIENT_NAME = 'AAPM'
WHERE PATIENT_IDENTIFIER = 'TG18-2002' ;

Why are you mixing the two different JOIN syntaxes? Simple rule: Never use commas in the FROM clause (and that goes for UPDATE as well). I think you intend:
update vna.patients p
patient_observations po
on p.patient_id = po.patient_id join
studies st
on po.study_id = st.study_id AND
st.patient_id = p.patient_id join
series s
on s.study_id = st.study_id join
instances i
on i.series_id = s.series_id join
sop_classes sc
on sc.sop_class_id = i.sop_class_id join
files f
on f.instance_id = i.instance_id left join
modalities m
on m.modality_id = s.modality_id left join
issuers iss
on (p.issuer_of_patient_identifier = iss.issuer_id)
set p.PATIENT_NAME = 'AAPM'
where p.PATIENT_IDENTIFIER = 'TG18-2002';
That seems way too complicated. I'm guessing you just want:
update vna.patients p
set p.PATIENT_NAME = 'AAPM'
where p.PATIENT_IDENTIFIER = 'TG18-2002';

The error message is very clear, the table patient_observations is listed twice in the table references in your query. Give the second one a different alias if you really need to join it again in the same query:
...
vna.issuers
join patient_observations as po2 on patients. ....
Otherwise, remove one of them.
Also try to use the ANSI SQL join syntax instead of this old syntax.

Related

One of two request make my server crash. Someone know? MYSQL

The first request make my server crash (The CPU go to 100%)
SELECT s.idSinistre
FROM test_apc_sinistres s
INNER JOIN apc_correspondances c ON c.idLiaison = s.idSinistre AND c.refCategorie = '69.1'
INNER JOIN apc_procedures_taches_sinistres p ON s.idSinistre = p.idSinistre
INNER JOIN apc_contacts co ON s.idAdb = co.idContact
INNER JOIN apc_parametres_adb pa ON pa.idAdb = co.idContact
WHERE s.refStatut = '62.2'
GROUP BY s.idSinistre;
select co.Nom, s.idSinistre, count(c.idMessage) as nbMEssage, count(p.id) as nbProc
from test_apc_sinistres s
inner join apc_correspondances c on c.idLiaison = s.idSinistre and c.refCategorie = '69.1'
inner join apc_procedures_taches_sinistres p on s.idSinistre = p.idSinistre
inner join apc_contacts co on s.idAdb = co.idContact
inner join apc_parametres_adb pa on pa.idAdb = co.idContact
where s.refStatut = '62.2'
group by s.idSinistre;
The only difference between this two is the data i select. Someone already have this issue?
Just re-check your columns one by one and you'll see that you are doing aggregates on all except one column.

Errors While Using IF statement in sql query

I am trying to make a query, which returns tipo_id from a table, depending on the value of this I want to join with another table, for example if tipo_id is 1 I want to join with table called p_read if tipo_id i want to join tv_read
this is what I tried to do.
SELECT ec.id,ec.estado,fv.id,fv.num_factura,fv.importe,fv.iva,fv.total,fv.fecha_consumo_inicio,fv.fecha_consumo_fin,
fv.fecha_factura, fv.fichero, c.total, l.tipo_id, lp.id_consumo FROM aldroges8.factura_venta fv
INNER JOIN aldroges8.lectura l ON fv.id=l.facturaVenta_id
INNER JOIN aldroges8.factura_cobro fc ON fc.facturaventa_id = fv.id
INNER JOIN aldroges8.cobros c ON c.id=fc.cobros_id
INNER JOIN aldroges8.estado_cobros ec ON ec.id = c.estado
IF (l.tipo_id=1)
INNER JOIN aldroges8.lectura_potencia lp ON l.id=lp.id
ELSE IF (l.tipo_id =3)
INNER JOIN aldroges8.lectura_tv_gas lp ON lp.id=l.id
WHERE fv.factura_enviada=1 AND fv.suministro_id=:id_contrato ORDER BY fv.fecha_factura DESC;
But i am getting this error.
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IF (l.tipo_id==1)
INNER JOIN aldroges8.lectura_potencia lp ON l.id=lp.id
ELSE' at line 7
So I want to know if there is a way on doing this if staments on a query, or do I need to make another query with tipo_id, thanks in advance
SELECT ec.id,ec.estado,fv.id,fv.num_factura,fv.importe,fv.iva,fv.total,fv.fecha_consumo_inicio,fv.fecha_consumo_fin,
fv.fecha_factura, fv.fichero, c.total, l.tipo_id,
/* Used case when statement to get the required result in that column */
case when l.tipo_id=1 then lp_1.id_consumo
when l.tipo_id=3 then lp_3.id_consumo end as id_consumo
FROM aldroges8.factura_venta fv
INNER JOIN aldroges8.lectura l ON fv.id=l.facturaVenta_id
INNER JOIN aldroges8.factura_cobro fc ON fc.facturaventa_id = fv.id
INNER JOIN aldroges8.cobros c ON c.id=fc.cobros_id
INNER JOIN aldroges8.estado_cobros ec ON ec.id = c.estado
left join aldroges8.lectura_potencia lp_1 ON l.id=lp_1.id
left join aldroges8.lectura_tv_gas lp_3 ON lp_3.id=l.id
WHERE fv.factura_enviada=1 AND fv.suministro_id=:id_contrato ORDER BY fv.fecha_factura DESC;
I would write this with the condition in the on clause and then use coalesce() in the select:
SELECT ec.id, ec.estado, fv.id, fv.num_factura, fv.importe, fv.iva,
fv.total, fv.fecha_consumo_inicio, fv.fecha_consumo_fin,
fv.fecha_factura, fv.fichero, c.total, l.tipo_id,
coalesce(lp_1.id_conumo, lp_3.id_consumo) as id_consumo
FROM aldroges8.factura_venta fv INNER JOIN
aldroges8.lectura l
ON fv.id = l.facturaVenta_id INNER JOIN
aldroges8.factura_cobro fc
ON fc.facturaventa_id = fv.id INNER JOIN
aldroges8.cobros c
ON c.id = fc.cobros_id INNER JOIN
aldroges8.estado_cobros ec
ON ec.id = c.estado LEFT JOIN
aldroges8.lectura_potencia lp_1
ON l.id = lp_1.id AND l.tipo_id = 1 LEFT JOIN
aldroges8.lectura_tv_gas lp_3
ON lp_3.id = l.id AND l.tipo_id = 3
WHERE fv.factura_enviada = 1 AND
fv.suministro_id = :id_contrato
ORDER BY fv.fecha_factura DESC;
The difference between doing the comparison in the ON verses in a CASE expression may seem subtle, but it can be important.
If there are multiple matches in either table, then putting the condition in the SELECT will result in duplicate rows.

MySQL can’t specify target table for update in FROM multiple table joins

I have searched for days on how to get around this error while trying to update a field from a multiple join table, with a minimum date from the same mutiple join tableset.
This is my Update statement:
update vtiger_projectmilestone
Inner Join vtiger_projectmilestonecf ON vtiger_projectmilestone.projectmilestoneid = vtiger_projectmilestonecf.projectmilestoneid
Inner Join vtiger_crmentity ON vtiger_projectmilestone.projectmilestoneid = vtcrmm.crmid
inner join vtiger_project on vtiger_project.projectid = vtiger_projectmilestone.projectid
Inner Join vtiger_crmentity vtcrmp ON vtcrmp.crmid = vtiger_project.projectid
set vtiger_projectmilestone.projectmilestonedate =
(select min(vtiger_projecttaskcf.cf_779)
FROM vtiger_projecttask tvpt
Inner Join vtiger_projecttaskcf tvptcf ON tvpt.projecttaskid = tvptcf.projecttaskid
Inner Join vtiger_projectmilestone tvpm ON tvpm.projectmilestoneid = tvpt.projecttasknumber
Inner Join vtiger_projectmilestonecf vtpmcf ON tvpm.projectmilestoneid = tvpmcf.projectmilestoneid
Inner Join vtiger_crmentity AS vtcrmm ON tvpm.projectmilestoneid = vtcrmm.crmid
Inner Join vtiger_crmentity AS vtcrmt ON tvpt.projecttaskid = vtcrmt.crmid
where tvpm.projectmilestone_no = vtiger_projectmilestone.projectmilestone_no
)
where vtiger_projectmilestone.projectid =
(select vtiger_project.projectid from vtiger_project
INNER JOIN vtiger_crmentity vtcrmp ON vtiger_project.projectid = vtcrmp.crmid
where vtcrmp.deleted = 0 order by vtiger_project.projectid desc limit 1)
and vtcrmp.deleted = 0
and vtcrmm.deleted = 0
and (vtiger_projectmilestone.projectmilestonedate is null or vtiger_projectmilestonecf.cf_763 is null) ;
This is a real life update query, not just a simple one table relationship.
I got round it by creating a temp table, inserting the value, updating the destination table and dropping the temp table.
I would really like to get this right, because it will come up more often.
All assistance is appreciated.
Cheers
Bernard Bailey
As stated in this answer you can't use the target update table in a subquery, as you can see in your query
SELECT min(vtiger_projecttaskcf.cf_779)
FROM vtiger_projecttask tvpt
Inner Join vtiger_projecttaskcf tvptcf ON tvpt.projecttaskid = tvptcf.projecttaskid
Inner Join
--using target update table in query
vtiger_projectmilestone tvpm ON tvpm.projectmilestoneid = tvpt.projecttasknumber
Inner Join vtiger_projectmilestonecf vtpmcf ON tvpm.projectmilestoneid = tvpmcf.projectmilestoneid
Inner Join vtiger_crmentity AS vtcrmm ON tvpm.projectmilestoneid = vtcrmm.crmid
Inner Join vtiger_crmentity AS vtcrmt ON tvpt.projecttaskid = vtcrmt.crmid
where tvpm.projectmilestone_no = vtiger_projectmilestone.projectmilestone_no
However i think that a work around is using the data from the table that you're updating, so instead of using joins, you could write some where conditions for example:
SELECT min(vtiger_projecttaskcf.cf_779)
FROM vtiger_projecttask tvpt
Inner Join vtiger_projecttaskcf tvptcf ON tvpt.projecttaskid = tvptcf.projecttaskid
Inner Join vtiger_projectmilestonecf vtpmcf ON tvpm.projectmilestoneid = tvpt.projecttasknumber
Inner Join vtiger_crmentity AS vtcrmm ON tvpt.projecttasknumber = vtcrmm.crmid
Inner Join vtiger_crmentity AS vtcrmt ON tvpt.projecttaskid = vtcrmt.crmid
where tvpm.projectmilestone_no = vtiger_projectmilestone.projectmilestone_no
--using the projectmilestoneid in a where clause
AND tvpt.projecttasknumber=vtiger_projectmilestone.projectmilestoneid
The caveat could be that probably you will get some performance issues, also, as I don't know the full schema, I can't tell if using other tables in the subquery instead of vtiger_projectmilestone will give you the right result

My MySQL query with two JOINs does not work

I have written the following query, which does not work. I want to know how to make it work. It is a two-JOIN query which fails to work.
SELECT oc_download.download_id, oc_product_to_download.download_id, oc_download_description.download_id
FROM oc_download
LEFT JOIN oc_product_to_download
ON oc_download.download_id = oc_product_to_download.download_id
LEFT JOIN
oc_download.download_id = oc_download_description.download_id
WHERE oc_product_to_download.product_id = 89
With single JOIN it works, but adding the second JOIN it fails. here is the clean working one-JOIN query:
SELECT oc_download.download_id, oc_product_to_download.download_id, oc_download_description.download_id
FROM oc_download
LEFT JOIN oc_product_to_download
ON oc_download.download_id = oc_product_to_download.download_id
WHERE oc_product_to_download.product_id = 89
How should I use multiple JOIN in one single query?
You forgot the table name in the 2nd join
SELECT d.download_id, p.download_id, dd.download_id
FROM oc_download d
LEFT JOIN oc_product_to_download p ON d.download_id = p.download_id
LEFT JOIN oc_download_description dd ON d.download_id = dd.download_id
WHERE p.product_id = 89
And your where clause turns your left join into an inner join. If you don't want that then change your query to
SELECT d.download_id, p.download_id, dd.download_id
FROM oc_download d
LEFT JOIN oc_product_to_download p ON d.download_id = p.download_id
AND p.product_id = 89
LEFT JOIN oc_download_description dd ON d.download_id = dd.download_id
This is your query fixed up a bit, using table aliases and proper join syntax:
SELECT od.download_id, opd.download_id, odd.download_id
FROM oc_download od LEFT JOIN
oc_product_to_download opd
ON od.download_id = opd.download_id LEFT JOIN
oc_download_description odd
od.download_id = odd.download_id
WHERE opd.product_id = 89;
You are using left join, but this appears to be unnecessary. The on clause is undoing the first outer join, turning it into an inner join (unmatched rows would have a NULL value, which are filtered out by the where clause). In fact, I would guess that your data has well defined foreign key relationships among the columns being joined. If this is the case, you should use inner join (or just join) for the query:
SELECT od.download_id, opd.download_id, odd.download_id
FROM oc_download od JOIN
oc_product_to_download opd
ON od.download_id = opd.download_id JOIN
oc_download_description odd
od.download_id = odd.download_id
WHERE opd.product_id = 89;
The left join is misleading because it implies that some keys might not match. You also run the risk of confusing the optimizer.

MySQL / PHP - 2 different arguments for 1 table

I have the following SQL:
$queryString = "
SELECT
iR.lastModified,
d.*,
c2.title as stakeholderTitle,
u.username as authorUsername,
c.title as authorContactName,
GROUP_CONCAT(iR.stakeholderRef) AS participants
FROM
informationRelationships iR,
contacts c2
INNER JOIN
debriefs d ON
d.id = iR.linkId
LEFT JOIN
users u ON
u.id = iR.author
LEFT JOIN
contacts c ON
c.ref = u.contactId
LEFT JOIN
debriefs d2 ON
d2.stakeholder = c2.ref
WHERE
(
iR.clientRef = '$clientRef' OR
iR.contactRef = '$contactRef'
)
AND
iR.projectRef = '$projectRef' AND
iR.type = 'Debrief'
GROUP BY
iR.linkId
ORDER BY
d.dateOfEngagement
";
notice how I require 2 different bits of data for the the contacts table.
So at one point, I need to match
c.ref = u.contactId
This will return one bit of information
but I also need a completely different grouping:
d2.stakeholder = c2.ref
Problem is that the title is the column i'm interested in for both:
c2.title as stakeholderTitle,
...
c.title as authorContactName
How do I go about doing this?
My current try is returning:
Error: Unknown column 'iR.linkId' in 'on clause'
I'm not sure I really understand what is happening here:
how to join two tables on common attributes in mysql and php?
EDIT::::---ANSWERED--zerkms
$queryString = "
SELECT
iR.lastModified,
d.*,
c2.title as stakeholderTitle,
u.username as authorUsername,
c.title as authorContactName,
GROUP_CONCAT(iR.stakeholderRef) AS participants
FROM
informationRelationships iR
INNER JOIN
debriefs d ON
d.id = iR.linkId
INNER JOIN
contacts c2 ON
d.stakeholder = c2.ref
LEFT JOIN
users u ON
u.id = iR.author
LEFT JOIN
contacts c ON
c.ref = u.contactId
WHERE
(
iR.clientRef = '$clientRef' OR
iR.contactRef = '$contactRef'
)
AND
iR.projectRef = '$projectRef' AND
iR.type = 'Debrief'
GROUP BY
iR.linkId
ORDER BY
d.dateOfEngagement
";
By re-ordering my query I have managed to get both columns in... Thanks zerkms!
You cannot mix implicit joins and explicit joins in a single query in mysql.
So
FROM informationRelationships iR,
contacts c2
should be rewritten to
FROM informationRelationships iR
INNER JOIN contacts c2 ON ...
Do not use cartesian product and joins in the same query (not subquery), here, use only joins (CROSS JOIN is the same as cartesian product).