Можете ли вы определить "буквальные" таблицы в SQL? - PullRequest
53 голосов
/ 12 июня 2009

Существует ли какой-либо синтаксис подзапроса SQL, позволяющий буквально определить временную таблицу?

Например, что-то вроде

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

Это избавит от необходимости выполнять два или три запроса: создать временную таблицу, поместить в нее данные, а затем использовать ее в объединении.

Я использую MySQL, но был бы заинтересован в других базах данных, которые могли бы делать что-то подобное.

Ответы [ 7 ]

52 голосов
/ 12 июня 2009

Полагаю, вы могли бы выполнить подзапрос с несколькими SELECT с в сочетании с UNION с.

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;
24 голосов
/ 13 июня 2011

Вы можете сделать это в 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 голосов
/ 12 июня 2009

В стандартном SQL (SQL 2003 - см. http://savage.net.au/SQL/), вы можете использовать:

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

С немного большей погоней вы также можете использовать:

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

Является ли эта работа в MySQL отдельной проблемой - но вы всегда можете попросить добавить ее или добавить самостоятельно (в этом прелесть Open Source).

14 голосов
/ 04 июня 2013

В Microsoft T-SQL 2008 формат выглядит так:

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

т.е. как упоминал Джонатан, но без ключевого слова table.

См:

6 голосов
/ 12 июня 2009

Я нашел эту ссылку Временные таблицы с 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;
0 голосов
/ 12 июня 2009

Одним словом, да. Еще лучше IMO, если ваш продукт SQL поддерживает общие табличные выражения (CTE), т. Е. Проще на глаз, чем использование подзапроса, плюс один и тот же CTE можно использовать несколько раз, например. это для «создания» таблицы последовательности уникальных целых чисел от 0 до 999 в SQL Server 2005 и выше:

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;

за исключением того, что вы действительно сделали бы что-то полезное с таблицей последовательности, например парсинг символов из столбца VARCHAR в базовой таблице.

ОДНАКО, если вы используете эту таблицу, которая состоит только из литеральных значений, многократных или многократных запросов, то почему бы не сделать ее базовой таблицей? Каждая база данных, которую я использую, имеет таблицу последовательностей целых чисел (обычно 100К строк), потому что она очень полезна.

0 голосов
/ 12 июня 2009

CREATE TEMPORARY TABLE (ID int, Имя char (100)) SELECT ....

Подробнее на: http://dev.mysql.com/doc/refman/5.0/en/create-table.html

(возле дна)

Преимущество заключается в том, что при возникновении проблем с заполнением таблицы (несоответствие типов данных) таблица автоматически удаляется.

В раннем ответе использовалось предложение FROM SELECT. Если возможно, используйте это, потому что это избавляет от головной боли при очистке стола.

Недостатком (который может не иметь значения) с FROM SELECT является размер созданного набора данных. Временная таблица позволяет индексировать, что может быть критическим. Для последующего запроса. Кажется нелогичным, но даже при наборе данных среднего размера (~ 1000 строк) может быть быстрее создать индекс для обработки запроса.

...