2008-11-28 23 views
72

Estoy tratando de usar MySQL para crear una vista con el "CON" cláusulaMySQL "CON" cláusula

WITH authorRating(aname, rating) AS 
    SELECT aname, AVG(quantity) 
    FROM book 
    GROUP BY aname 

Pero no parece que MySQL soporta esto.

Pensé que esto era bastante estándar y estoy seguro de que Oracle apoya esto. ¿Hay alguna forma de obligar a MySQL a usar la cláusula "CON"? Lo he intentado con el motor MyISAM e innoDB. Ambos no funcionan.

Respuesta

0

Subselects como valores generalmente debe estar entre paréntesis.

Actualización: no estoy seguro de qué sintaxis está tratando de usar. ¿Podrías mostrar una declaración más completa? CREAR VISTA toma una instrucción SELECT que, afaik, puede tener un WITH pero solo donde sería válido en un SELECT independiente.

Actualización 2: err, estaba pensando en CASE, no CON. Google no muestra ninguna sintaxis WITH especial para Oracle, excepto la opción WITH CHECK OPTION que también admite mysql. Comience por describir lo que está tratando de lograr?

Actualización 3: simplemente a ojo, que significa algo como esto:

SELECT ... FROM foo, (seleccione aname promedio (cantidad) como la calificación del grupo de lectura por aname) como authorRating donde ...

+0

oracle 9 y superior admite con – EvilTeach

5

Oracle no admite CON.

Se vería así.

WITH emps as (SELECT * FROM Employees) 
SELECT * FROM emps WHERE ID < 20 
UNION ALL 
SELECT * FROM emps where Sex = 'F' 

@ysth WITH es difícil de buscar en Google porque es una palabra común que normalmente se excluye de las búsquedas.

Le recomendamos que consulte el SELECT docs para ver cómo funciona el factorización de subconsulta.

Sé que esto no responde al OP, pero estoy limpiando cualquier confusión que pueda haber comenzado.

+0

No resolvió mi confusión de todos modos. ¿Estás diciendo que no hay una cláusula WITH pero hay una declaración WITH? – ysth

+0

Ah, ya veo. Es una cláusula de una selección que precede a la selección. ¿Se puede usar también en CREATE VIEW? ¿Cómo es diferente de unirse a una subselección? No veo ejemplos en línea donde el nombre después del CON tenga parámetros: ¿cómo funcionan? – ysth

+0

Es muy diferente. Observe que el mismo subgrupo se usa dos veces sin tener que definirlo dos veces. Claro que puedes copiar/pegar esa misma consulta, pero este es un ejemplo simple. Imagine si la cláusula WITH continuara para una página y se usara 4 veces en la consulta principal. lo apreciarás entonces –

84

Actualización: MySQL 8.0 finalmente está obteniendo la característica de expresiones comunes de tablas, incluyendo CTE recursivas.

Aquí es un blog anunciando que: http://mysqlserverteam.com/mysql-8-0-labs-recursive-common-table-expressions-in-mysql-ctes/

continuación es mi respuesta anterior, que escribí originalmente en 2008.


MySQL no soporta consultas utilizando la sintaxis WITH definido en SQL-99, también se llama Common Table Expressions.

Esta ha sido una de estas solicitudes para MySQL desde enero de 2006: http://bugs.mysql.com/bug.php?id=16244

Otros productos RDBMS que soportan las expresiones de tabla comunes: liberación

Otras bases de datos que carecen de apoyo a la cláusula (a partir de febrero de 2014):

+0

SQLite admite la [cláusula WITH] (https://www.sqlite.org/lang_with.html) a partir de [versión 3.8.3] (http://www.sqlite.org/changes.html#version_3_8_3) publicada en 2014-02-03. – Martijn

+0

Agregué H2 y Firebird a la lista. –

+0

@a_horse_with_no_name, gracias por las adiciones. ¡Tal vez podamos avergonzar a MySQL para aumentar la prioridad de esta antigua solicitud de funciones! –

11

Usted tiene el derecho de sintaxis:

WITH AuthorRating(AuthorName, AuthorRating) AS 
    SELECT aname   AS AuthorName, 
      AVG(quantity) AS AuthorRating 
    FROM Book 
    GROUP By Book.aname 

Sin embargo, como otros han mencionado, MySQL no es compatible con este comando. WITH se agregó en SQL: 1999; la versión más nueva del estándar SQL es SQL: 2008. Puede encontrar más información sobre las bases de datos compatibles con SQL: las diversas funciones de 1999 en Wikipedia.

MySQL tradicionalmente ha quedado algo rezagado en cuanto al estándar SQL, mientras que las bases de datos comerciales como Oracle, SQL Server (recientemente) y DB2 las han seguido un poco más de cerca. PostgreSQL es típicamente bastante compatible con los estándares también.

Es posible que desee ver la hoja de ruta de MySQL; No estoy del todo seguro de cuándo se admitirá esta característica, pero es genial para crear consultas de resumen legibles.

10

Usted puede estar interesado en somethinkg así:

select * from (
    select * from table 
) as Subquery 
+0

, ¿puede explicar Subquery, por favor? podría tener seleccionar * de ( (seleccionar * de la tabla 1) UNION TODO (seleccionar * de la tabla 2) ) Agrupar ¿Por algo? –

+1

@Kathy Hola, 'Subquery' es el nombre que utilicé para la tabla derivada. Cuando usa 'from (...)' crea algo así como una tabla temporal (una tabla derivada) y requiere un nombre. Es por eso que usé 'como Subquery'. Respondiendo a su pregunta, sí, puede, pero tendrá que poner un nombre en la tabla derivada externa (justo antes del 'Agrupar por'). Espero que haya ayudado. –

+0

causa que mi DB se cuelgue ... –

1

¿Alguna vez ha tratado de tabla temporal? Esto resolvió mi convern:

create temporary table abc (
column1 varchar(255) 
column2 decimal 
); 
insert into abc 
select ... 
or otherwise 
insert into abc 
values ('text', 5.5), ('text2', 0815.8); 

continuación, puede utilizar esta tabla en todas las seleccione en esta sesión:

select * from abc inner join users on ...; 
+0

Tengo para tener en cuenta: http://stackoverflow.com/questions/343402/getting-around-mysql-cant-reopen-table-error no se puede abrir la Tabla dos veces :-( – Claus

+0

Mi Sollution para pequeños conjuntos de datos en tablas: create table abc2 like abc; insertar en abc2 select * from abc; – Claus

1

Sobre la base de la respuesta de @Mosty mostacho, aquí es cómo se puede hacer algo equivalente en MySQL, para un caso específico de determinación de qué entradas no existen en una tabla, y no están en ninguna otra base de datos.

select col1 from (
    select 'value1' as col1 union 
    select 'value2' as col1 union 
    select 'value3' as col1 
) as subquery 
left join mytable as mytable.mycol = col1 
where mytable.mycol is null 
order by col1 

Es posible que desee utilizar un editor de texto con capacidad para macros para convertir una lista de valores de la cláusula union select citado.

Cuestiones relacionadas