without all sql union distinct union-all

without - Sql Union All*con*"distinto"



union distinct oracle (8)

UNION une dos resultados y elimina duplicados, mientras que UNION ALL no elimina duplicados. UNION también ordena la salida final.

Lo que quiero es UNION ALL sin duplicados y sin la clasificación. ¿Es eso posible?

La razón de esto es que quiero que el resultado de la primera consulta esté por encima del resultado final, y la segunda consulta por debajo. (Y cada uno ordenado como si se ejecutaran individualmente)


"UNION también clasifica el resultado final", solo como un artefacto de implementación. De ninguna manera se garantiza que realice la clasificación, y si necesita un orden particular, debe especificarlo con una cláusula ORDER BY . De lo contrario, el orden de salida es lo que sea más conveniente para el servidor.

Como tal, su solicitud de una función que ejecute UNION ALL pero que elimine duplicados es fácil: se llama UNION .

De su aclaración, también parece creer que un UNION ALL devolverá todos los resultados de la primera consulta antes que los resultados de las consultas posteriores. Esto tampoco está garantizado. Nuevamente, la única forma de lograr un orden particular es especificarlo usando una cláusula ORDER BY .


¡Me doy cuenta de que esta pregunta recibe muchas visitas, por lo que primero abordaré una pregunta que no hizo !

Respecto al título. Para lograr un "Sql Union All con " distinto "", simplemente reemplace UNION ALL con UNION . Esto tiene el efecto de eliminar duplicados.

Para su pregunta específica, dada la aclaración "La primera consulta debe tener" prioridad ", por lo que los duplicados deben eliminarse de la parte inferior" puede usar

SELECT col1, col2, MIN(grp) AS source_group FROM (SELECT 1 AS grp, col1, col2 FROM t1 UNION ALL SELECT 2 AS grp, col1, col2 FROM t2) AS t GROUP BY col1, col2 ORDER BY MIN(grp), col1


1,1: select 1 from dual union all select 1 from dual 1: select 1 from dual union select 1 from dual


Considere estas tablas (código SQL estándar, se ejecuta en SQL Server 2008):

WITH A AS ( SELECT * FROM ( VALUES (1), (2), (3), (4), (5), (6) ) AS T (col) ), B AS ( SELECT * FROM ( VALUES (9), (8), (7), (6), (5), (4) ) AS T (col) ), ...

El efecto deseado es este para ordenar la tabla A por orden ascendente, ordenar la tabla B por orden descendente y luego unir los dos, eliminar duplicados, mantener el orden antes de la unión y dejar los resultados de la tabla A en la "parte superior" con la tabla B en la parte "inferior" ej. (código pesudo)

( SELECT * FROM A ORDER BY col ) UNION ( SELECT * FROM B ORDER BY col DESC );

Por supuesto, esto no funcionará en SQL porque solo puede haber una cláusula ORDER BY y solo se puede aplicar a la expresión de la tabla de nivel superior (o cualquiera que sea el resultado de una consulta SELECT se denomina "conjunto de resultados" ").

Lo primero que hay que abordar es la intersección entre las dos tablas, en este caso los valores 4 , 5 y 6 . La forma en que se debe ordenar la intersección debe especificarse en el código SQL, por lo tanto, ¡es deseable que el diseñador lo especifique también! (es decir, la persona que hace la pregunta, en este caso).

La implicación en este caso parece ser que la intersección ("duplicados") debe ordenarse dentro de los resultados para la tabla A. Por lo tanto, el conjunto de resultados ordenado debe verse así:

VALUES (1), -- A including intersection, ascending (2), -- A including intersection, ascending (3), -- A including intersection, ascending (4), -- A including intersection, ascending (5), -- A including intersection, ascending (6), -- A including intersection, ascending (9), -- B only, descending (8), -- B only, descending (7), -- B only, descending

Nota en SQL "arriba" y "abajo" no tiene un significado inferente y una tabla (que no sea un conjunto de resultados) no tiene orden inherente. También (para abreviar una larga historia) considere que UNION elimina las filas duplicadas por implicación y debe aplicarse antes de ORDER BY . La conclusión debe ser que el orden de clasificación de cada tabla debe definirse explícitamente al exponer una columna de ordenamiento antes de unirse. Para esto podemos usar la función de ventana ROW_NUMBER() p. Ej.

... A_ranked AS ( SELECT col, ROW_NUMBER() OVER (ORDER BY col) AS sort_order_1 FROM A -- include the intersection ), B_ranked AS ( SELECT *, ROW_NUMBER() OVER (ORDER BY col DESC) AS sort_order_1 FROM B WHERE NOT EXISTS ( -- exclude the intersection SELECT * FROM A WHERE A.col = B.col ) ) SELECT *, 1 AS sort_order_0 FROM A_ranked UNION SELECT *, 2 AS sort_order_0 FROM B_ranked ORDER BY sort_order_0, sort_order_1;


La clasificación se usa para eliminar los duplicados, y está implícita para las consultas DISTINCT y UNION (pero no UNION ALL ); aún puede especificar las columnas que prefiere ordenar si las necesita ordenadas por columnas específicas.

Por ejemplo, si desea ordenar por conjuntos de resultados, puede introducir una columna adicional y ordenar por ese primero:

SELECT foo, bar, 1 as ResultSet FROM Foo WHERE bar = 1 UNION SELECT foo, bar, 2 as ResultSet FROM Foo WHERE bar = 3 UNION SELECT foo, bar, 3 as ResultSet FROM Foo WHERE bar = 2 ORDER BY ResultSet


Supongo que sus tablas son table1 y table2 respectivamente, y su solución es;

(select * from table1 MINUS select * from table2) UNION ALL (select * from table2 MINUS select * from table1)


SELECT *, 1 AS sort_order FROM table1 EXCEPT SELECT *, 1 AS sort_order FROM table2 UNION SELECT *, 1 AS sort_order FROM table1 INTERSECT SELECT *, 1 AS sort_order FROM table2 UNION SELECT *, 2 AS sort_order FROM table2 EXCEPT SELECT *, 2 AS sort_order FROM table1 ORDER BY sort_order;

Pero la respuesta real es: aparte de la cláusula ORDER BY , el orden de clasificación será arbitrario y no estará garantizado.


select T.Col1, T.Col2, T.Sort from ( select T.Col1, T.Col2, T.Sort, rank() over(partition by T.Col1, T.Col2 order by T.Sort) as rn from ( select Col1, Col2, 1 as Sort from Table1 union all select Col1, Col2, 2 from Table2 ) as T ) as T where T.rn = 1 order by T.Sort