with left joins inner ejemplo after sql oracle

sql - left - transform access ejemplo



ANSI se une a la cláusula "where clause" (10)

Desde entonces, aprendí que esto no es una sintaxis SQL estándar.

Eso no es del todo cierto. La sintaxis "a,b where" es del estándar ansi-89, la sintaxis "a join b on" es ansi-92. Sin embargo, la sintaxis 89 está en desuso , lo que significa que no debe usarla para nuevas consultas.

Además, hay algunas situaciones en las que el estilo anterior carece de poder expresivo, especialmente con respecto a las combinaciones externas o las consultas complejas.

Puede ser un dolor ir a través de la cláusula where tratando de elegir condiciones de unión. Para cualquier cosa, más de una, unirse al viejo estilo es el mal absoluto. Y una vez que conozca el nuevo estilo, también puede seguir usándolo.

Desarrollo contra bases de datos Oracle. Cuando necesito escribir manualmente (no uso un ORM como hibernar), coloco declaraciones de unión en las secciones cláusula where.

por ejemplo (esto es simplista solo para ilustrar el estilo):

Select * from customers c, invoices i, shipment_info si where c.customer_id = i.customer_id and i.amount > 999.99 and i.invoice_id = si.invoice_id(+) -- added to show how outer joins can be supported in this style order by i.amount, c.name

Aprendí este estilo de un DBA de Oracle antiguo. Desde entonces, aprendí que esto no es una sintaxis SQL estándar. Además de ser no estándar y mucho menos portátil de base de datos, ¿hay alguna otra repercusión al usar este formato?

Gracias, Jay


Algunas personas dirán que este estilo es menos legible, pero esa es una cuestión de hábito. Desde el punto de vista del rendimiento, no importa, ya que el optimizador de consultas se ocupa de eso.


El mayor problema con el que me he topado con este formato es la tendencia a olvidar la cláusula WHERE alguna combinación, lo que resulta en un producto cartesiano. Esto es particularmente común (al menos para mí) al agregar una tabla nueva a la consulta. Por ejemplo, supongamos que una mesa ADDRESSES es lanzada a la mezcla y su mente es un poco olvidadiza:

SELECT * FROM customers c, invoices i, addresses a WHERE c.customer_id = i.customer_id AND i.amount > 999.99 ORDER BY i.amount, c.name

¡Auge! ¡Producto cartesiano! :)


En realidad, esta sintaxis es más portable que un JOIN, porque funcionará con casi cualquier base de datos, mientras que no todos admiten la sintaxis JOIN (Oracle Lite no lo hace, por ejemplo [a menos que esto haya cambiado recientemente]).


Esta es la sintaxis de Transact SQL, y no estoy muy seguro de lo "poco viable" que es, es la sintaxis principal utilizada en Sybase, por ejemplo (Sybase también admite la sintaxis ANSI) así como muchas otras bases de datos (si no todas) .

Los principales beneficios de la sintaxis ANSI es que le permite escribir algunas uniones encadenadas bastante complicadas que T-SQL prohíbe


Esta es una sintaxis SQL estándar, solo un estándar más antiguo que JOIN. Hay una razón por la cual la sintaxis ha evolucionado y debe usar la sintaxis JOIN más nueva porque:

  1. Es más expresivo, indica claramente qué tablas están UNIDAS, el orden UNIR, qué condiciones se aplican a qué UNIRSE y separa las condiciones de filtrado DONDE de las condiciones UNIR.

  2. Es compatible con LEFT, RIGHT y FULL OUTER JOINs, lo que no ocurre con la sintaxis WHERE.

No creo que encuentre el JOERE-type JOIN sustancialmente menos portátil que la sintaxis JOIN.


No me gusta el estilo porque hace más difícil determinar qué cláusulas WHERE son para simular JOINs y cuáles son para filtros reales, y no me gusta el código que hace innecesariamente difícil determinar la intención original del programador.


Realmente depende de los hábitos, pero siempre he encontrado que la sintaxis separada de la coma de Oracle es más natural. La primera razón es que creo que el uso (INNER) JOIN disminuye la legibilidad. El segundo es sobre flexibilidad. Al final, una unión es un producto cartesiano por definición. No necesariamente tiene que restringir los resultados en función de los ID de ambas tablas. Aunque muy rara vez, uno podría necesitar un producto cartesiano de dos tablas. Restringirlos basados ​​en ID es solo una práctica muy razonable, pero NO UNA REGLA . Sin embargo, si utiliza la palabra clave JOIN en, por ejemplo, SQL Server, no le permitirá omitir la palabra clave ON . Supongamos que quiere crear una lista de combinación. Tienes que hacer esto:

SELECT * FROM numbers JOIN letters ON 1=1

Aparte de eso, creo que la sintaxis (+) de Oracle también es muy razonable. Es una buena forma de decir: " Agregue este registro al conjunto de resultados también, incluso si es nulo " . Es mucho mejor que la sintaxis RIGHT / LEFT JOIN , porque de hecho ¡no hay izquierda ni derecha! Cuando desee unir 10 tablas con diferentes tipos de uniones externas, se confunde qué tabla está en el "lado izquierdo" y cuál a la derecha.

Por cierto, como comentario más general, no creo que la portabilidad SQL ya exista en el mundo práctico. El SQL estándar es tan pobre y la expresividad de una sintaxis específica de DBMS diversa se exige con tanta frecuencia, que no creo que el código SQL 100% portátil sea un objetivo alcanzable. La evidencia más obvia de mi observación es el problema del viejo número de fila . Simplemente busque en cualquier foro el " número de fila sql" , incluido SO, y verá cientos de publicaciones que preguntan cómo se puede lograr en un DBMS específico. Similar y relacionado con eso, por lo que limita el número de filas devueltas , por ejemplo ..


Siempre que no use la función de combinación natural ANSI, estoy de acuerdo.

Encontré esta cita de - ScottCher, estoy totalmente de acuerdo:

Creo que la sintaxis WHERE es más fácil de leer que INNER JOIN, supongo que es como Vegemite. La mayoría de las personas en el mundo probablemente lo encuentren desagradable, pero los niños criados comiendo lo aman.


La combinación de estilo antiguo es totalmente incorrecta en algunos casos (las uniones externas son las culpables). Aunque son más o menos equivalentes al usar uniones internas, pueden generar resultados incorrectos con uniones externas, especialmente si las columnas en el lado externo pueden ser nulas. Esto se debe a que cuando se usa la sintaxis anterior, las condiciones de unión no se evalúan lógicamente hasta que se haya construido todo el conjunto de resultados, simplemente no es posible expresar una condición en una columna desde el exterior de una unión que filtrará registros cuando la columna pueda ser nulo porque no hay un registro coincidente.

Como ejemplo:

Seleccione todos los clientes y la suma de las ventas de widgets en todas sus facturas en el mes de agosto, donde se procesó la factura (Invoice.ProcessDate is not null)

utilizando la nueva sintaxis de unión ANSI-92

Select c.name, Sum(d.Amount) From customer c Left Join Invoice I On i.custId = c.custId And i.SalesDate Between ''8/1/2009'' and ''8/31/2009 23:59:59'' And i.ProcessDate Is Not Null Left Join InvoiceDetails d On d.InvoiceId = i.InvoiceId And d.Product = ''widget'' Group By c.Name

Intente hacer esto con la sintaxis anterior ... Porque al usar la sintaxis de estilo anterior, todas las condiciones en la cláusula where se evalúan / aplican ANTES de que se agreguen las filas "externas", todas las filas de la Factura Sin Procesar se agregarán de nuevo al conjunto de resultados final ... Así que esto no es posible con la sintaxis antigua: cualquier cosa que intente filtrar las facturas con nulo Fechas procesadas eliminará a los clientes ... la única alternativa es usar una subconsulta correlacionada.