你能在SQL中定义"文字"表吗?

tho*_*ter 55 mysql sql subquery temp-tables

是否有任何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
Run Code Online (Sandbox Code Playgroud)

这将节省必须执行两个或三个查询:创建临时表,将数据放入其中,然后在连接中使用它.

我正在使用MySQL,但会对其他可以做类似事情的数据库感兴趣.

Bli*_*ixt 53

我想你可以做几个SELECTs与UNIONs 结合的子查询.

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;
Run Code Online (Sandbox Code Playgroud)


dvv*_*dvv 24

你可以在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
Run Code Online (Sandbox Code Playgroud)

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

  • PostgreSQL FTW。 (2认同)
  • 问题是关于MySQL的 (2认同)

Jon*_*ler 19

在标准SQL(SQL 2003 - 请参阅http://savage.net.au/SQL/)中,您可以使用:

INSERT INTO SomeTable(Id, Count) VALUES (1, 7), (2, 6), (3, 13), ...
Run Code Online (Sandbox Code Playgroud)

随着更多的追逐,你也可以使用:

SELECT * FROM TABLE(VALUES (1,7), (2, 6), (3, 13), ...) AS SomeTable(Id, Count)
Run Code Online (Sandbox Code Playgroud)

这些是否在MySQL中工作是一个单独的问题 - 但你总是可以要求添加它,或者自己添加它(这就是开源之美).


小智 15

在Microsoft T-SQL 2008中,格式为:

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

就像Jonathan上面提到的那样,但没有'table'关键字.

看到:


Doi*_*oin 9

从 MariaDB v10.3.3 和 MySQL v8.0.19 开始,您现在就可以做到这一点

请参阅文档: MariaDBMySQL

玛丽亚数据库:

WITH literaltable (id,count) AS (VALUES (1,7),(2,6),(3,13),(4,12),(5,9))
SELECT MAX(count) AS max,COUNT(*) AS count FROM literaltable
Run Code Online (Sandbox Code Playgroud)

WITH在这里使用了 a ,因为 MariaDB 没有为VALUES .... 您可以在没有列名的联合中使用它:

SELECT 1 AS id,7 AS count UNION ALL VALUES (2,6),(3,13),(4,12),(5,9) ORDER BY count DESC
Run Code Online (Sandbox Code Playgroud)

尽管文档似乎没有提及它,但您甚至可以将其用作顶级查询:

VALUES (1,7),(2,6),(3,13),(4,12),(5,9) ORDER BY 2 DESC
Run Code Online (Sandbox Code Playgroud)

实际的列名实际上只是第一行值,因此您甚至可以这样做(尽管它不优雅,并且您可能会遇到重复的列名错误):

SELECT MAX(`7`) AS max,COUNT(*) AS count FROM (VALUES (1,7),(2,6),(3,13),(4,12),(5,9)) literaltable
Run Code Online (Sandbox Code Playgroud)

MySQL:

我现在没有可供测试的 MySQL v8.0.19 实例,但根据文档,其中一个应该可以工作:

SELECT MAX(column_1) AS max,COUNT(*) AS count FROM (VALUES ROW(1,7), ROW(2,6), ROW(3,13), ROW(4,12), ROW(5,9)) literaltable

SELECT MAX(data) AS max,COUNT(*) AS count FROM (VALUES ROW(1,7), ROW(2,6), ROW(3,13), ROW(4,12), ROW(5,9)) literaltable(id,data)
Run Code Online (Sandbox Code Playgroud)

与 MariaDB 不同,MySQL 提供自动列名称 column_0、column_1、column_2 等,并且还支持在引用子查询时重命名子查询的所有列。

我不确定,但是这个开发工作日志页面似乎表明 MySQL 也实现了更短的语法(省略“ROW”,如 MariaDB),或者他们将在不久的将来实现。

  • 在[8.0.19的发布页面](https://dev.mysql.com/blog-archive/the-mysql-8-0-19-maintenance-release-is-generally-available/)中,他们声明:“ "" 由于与 VALUES() 函数(MySQL 非标准功能)冲突,我们决定使用表值构造函数的 SQL 标准详细形式: VALUES ROW(1, 2) """ 所以不幸的是我不'我不认为他们计划支持没有 ROW 的 VALUES (2认同)

小智 6

我发现这个链接临时表与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;
Run Code Online (Sandbox Code Playgroud)