¿Puede definir tablas "literales" en SQL?


¿Existe alguna sintaxis de subconsulta SQL que le permita definir, literalmente, una tabla temporal?

Por ejemplo, algo como

SELECT
  MAX(count) AS max,
  COUNT(*) AS count
FROM
  (
    (1 AS id, 7 AS count),
    (2, 6),
    (3, 13),
    (4, 12),
    (5, 9)
  ) AS mytable
  INNER JOIN someothertable ON someothertable.id=mytable.id

Esto ahorraría tener que hacer dos o tres consultas: crear una tabla temporal, poner datos en ella, luego usarla en una combinación.

Estoy usando MySQL pero estaría interesado en otras bases de datos que podrían hacer algo así.

Author: thomasrutter, 2009-06-12

7 answers

Supongo que podrías hacer una subconsulta con varios SELECTs combinados con UNION s.

SELECT a, b, c, d
FROM (
    SELECT 1 AS a, 2 AS b, 3 AS c, 4 AS d
    UNION ALL 
    SELECT 5 , 6, 7, 8
) AS temp;
 45
Author: Blixt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-12 06:44:23

Puede hacerlo en PostgreSQL:

=> select * from (values (1,7), (2,6), (3,13), (4,12), (5,9) ) x(id, count);
 id | count 
----+-------
  1 |     7
  2 |     6
  3 |    13
  4 |    12
  5 |     9

Http://www.postgresql.org/docs/8.2/static/sql-values.html

 18
Author: dvv,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-11 22:11:18

En SQL estándar (SQL 2003-ver http://savage.net.au/SQL/) puede utilizar:

INSERT INTO SomeTable(Id, Count) VALUES (1, 7), (2, 6), (3, 13), ...

Con un poco más de persecución, también puedes usar:

SELECT * FROM TABLE(VALUES (1,7), (2, 6), (3, 13), ...) AS SomeTable(Id, Count)

Si estos funcionan en MySQL es un problema separado, pero siempre puede pedir que se agregue, o agregarlo usted mismo (esa es la belleza del Código abierto).

 16
Author: Jonathan Leffler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-12 07:02:47

En Microsoft T-SQL 2008 el formato es:

SELECT a, b FROM (VALUES (1, 2), (3, 4), (5, 6), (7, 8), (9, 10) ) AS MyTable(a, b)

Es decir, como Jonathan mencionó anteriormente, pero sin la palabra clave 'table'.

Véase:

 12
Author: Pete,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-06-03 22:36:13

He encontrado este enlace Tablas Temporales Con MySQL

CREATE TEMPORARY TABLE TempTable ( ID int, Name char(100) ) TYPE=HEAP; 

INSERT INTO TempTable VALUES( 1, "Foo bar" ); 

SELECT * FROM TempTable; 

DROP TABLE TempTable;
 6
Author: ole6ka,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-12 06:49:25

CREAR TABLA TEMPORAL ( ID int, Nombre char(100) ) SELECCIONAR ....

Lea más en: http://dev.mysql.com/doc/refman/5.0/en/create-table.html

(cerca de la parte inferior )

Esto tiene la ventaja de que si hay algún problema al rellenar la tabla ( desajuste de tipo de datos ) la tabla se elimina automáticamente.

Una respuesta temprana usaba una cláusula FROM SELECT. Si es posible utilizar que porque ahorra el dolor de cabeza de la limpieza de la mesa.

Desventaja ( lo que puede no importar) con el DE SELECCIONAR es qué tan grande es el conjunto de datos creado. Una tabla temporal permite la indexación que puede ser crítica. Para la consulta posterior. Parece contrario a lo intuitivo, pero incluso con un conjunto de datos de tamaño mediano ( ~1000 filas), puede ser más rápido tener un índice creado para que la consulta funcione.

 0
Author: Pat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-12 07:14:26

En una palabra, sí. Aún mejor IMO si su producto SQL admite expresiones de tabla comunes (CTE), es decir, más fácil a la vista que usar una subconsulta más el mismo CTE se puede usar varias veces, por ejemplo, esto para 'crear' una tabla de secuencia de enteros únicos entre 0 y 999 en SQL Server 2005 y superiores:

WITH Digits (nbr) AS 
(
 SELECT 0 AS nbr UNION ALL SELECT 1 UNION ALL SELECT 2 
 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 
 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 
 UNION ALL SELECT 9 
), 
Sequence (seq) AS
(
 SELECT Units.nbr + Tens.nbr + Hundreds.nbr 
   FROM Digits AS Units
        CROSS JOIN Digits AS Tens
        CROSS JOIN Digits AS Hundreds
)
SELECT S1.seq 
  FROM Sequence AS S1;

Excepto que realmente haría algo útil con la tabla de secuencia, por ejemplo, analizar los caracteres de una columna VARCHAR en una tabla base.

Sin EMBARGO, si está utilizando esta tabla, que consiste solo en valores literales, múltiples veces o en múltiples consultas, ¿por qué no convertirla en una tabla base en primer lugar? Cada base de datos que uso tiene una tabla de Secuencia de enteros (generalmente 100K filas) porque es muy útil en general.

 0
Author: onedaywhen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-12 09:07:05