问题
I need to write this query using inner joins or right/left joins but I don't know how to start:
select * from radicados where asignado =
(select estudianteid from estudiantes where usuario =
(select usuarioid from usuarios where nombre = $nombre_usuario))
But I don't know how to do the same with joins.
I think this must be something like:
select * from radicados inner join usuarios on usuarioid=usuario
回答1:
It appears you want something like this:
select radicados.*
from
radicados
join estudiantes
on radicados.asignado = estudiantes.estudianteid
join usarios
on estudiantes.usario = usarios.usarioid
where usarios.nombre = $nombre_usuario
In constructing such a query, start with the FROM
clause. Join together the various tables containing the needed data, based on the relationships between them. If needed, add a WHERE
clause describing any additional conditions on which you want to filter the result of your join. Then fill in the SELECT
list as appropriate.
Under some circumstances you may need to add other clauses, too (ORDER BY
, GROUP BY
, etc.), but that's not bad once you understand basic queries.
回答2:
This is the same as
SELECT estudiantes.* FROM radicados
JOIN estudiantes ON estudianteid = asignado
JOIN usuarioid ON usuarioid = usuario
WHERE nombre = $nombre_usuario
I assume here that column names are unique. If not you have to add table names to field names.
回答3:
Don't think in terms of picking individual values from tables. Think in terms of rows that meet criteria. Even better think of a table as holding rows that make a corresponding statement true and a query as calculating rows that make a corresponding statement true. First you pick the statement; then you write the query that corresponds to that statement. Here is how to design queries.
//*
all radicados columns of the rows where
a subrow is IN radicados AND a subrow is IN estudiantes
AND asignado = estudianteid
AND a subrow is IN usarios
AND usuarioid = usuario
AND nombre = $nombre_usuario
*//
select radicados.*
from radicados
join estudiantes on estudianteid = asignado
join usuarios on usarioid = usario
and nombre = $nombre_usuario
When your original query reports no runtime errors then this query returns the same rows. But it is not necessarily an equivalent query because your original query reports a runtime error when there is more than one user id (usarios usuarioid) for the given user number (usuarios nombre) or more than one student id (estudiantes estudianteid) for the chosen user id (usuarios usario).
//*
all columns of the radicados rows where
asignado =
the one estudianteid shared by the estudiantes rows where
usuario =
the one usuarioid shared by the usuarios rows where
nombre = $nombre_usuario
*//
select * from radicados where asignado = (select estudianteid from estudiantes where usuario = (select usuarioid from usuarios where nombre = $nombre_usuario ) )
This is because expression value = (SELECT ...)
is runtime-error-free only if the SELECT
returns a table with one column and one row. If so it compares value to the one value in that table but otherwise it gives an error.
If you gave your table definitions and if you declared certain candidate key (PRIMARY KEY
or UNIQUE NOT NULL
) or FOREIGN KEY
constraints then we might know that there will be no errors. When you know that there will be no errors then you should declare the corresponding constraints.
Although probably this new query is the one that you really wanted anyway.
来源:https://stackoverflow.com/questions/28202970/replace-comparison-to-scalar-subquery-by-inner-join-or-left-right-join