Replace comparison to scalar subquery by inner join or left/right join

夙愿已清 提交于 2021-01-29 04:29:10

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!