sqlite 如何命名VALUES子句中的列?

4zcjmb1e  于 2022-11-14  发布在  SQLite
关注(0)|答案(6)|浏览(260)

对于SQLite 3.17.0中的此查询:

select T.* from (values (1),(2),(3),(4),(5)) as T;

T的第一列没有名称:
这一点

1
2
3
4
5
如何为T的第一列命名/别名,或者按索引引用它?

au9on6nz

au9on6nz1#

with cte(my_column_alias) as 
  (values (1),(2),(3),(4),(5))
select * from cte;
vm0i2vca

vm0i2vca2#

VALUES form of a query没有任何机制让您指定列名。(VALUES子句旨在用于CTE或视图中,您可以在其中指定别处的列名。)
碰巧的是,值返回的列确实有名称(但它们没有文档记录):

sqlite> .header on
sqlite> .mode columns
sqlite> values (42);
column1
----------
42

在任何情况下,即使名称在子查询中不存在,空列名称也不成问题:

select "" from (values (1),(2),(3),(4),(5));

要应用列名,请用CTE将其括起来:

WITH T(my_column) AS (
  VALUES (1),(2),(3),(4),(5)
)
SELECT * FROM T;

或者使用复合查询(WHERE 0隐藏第一个查询中的行):

SELECT NULL AS my_column WHERE 0
UNION ALL
VALUES (1),(2),(3),(4),(5);
chy5wohz

chy5wohz3#

虽然我推荐@Catherine提供的CTE答案--因为它不仅在某些情况下似乎比我提供的答案执行得更快,而且鼓励与可重用性和单一责任等原则相关的开发模式和方法。
尽管这个答案(可能还有所有这些答案)取决于PRAGMA设置(我目前对此没有足够的知识来介绍),但似乎可以同时引用生成的列名和它们的别名。
也就是说,VALUES表的列是使用列标题生成的:column1column2等等;因此,您只需通过显式引用特定的、生成的列名来为列指定别名。

SELECT
   v.[column1] [Id]
  ,v.[column2] [Name]
FROM (VALUES (1, 'Alex'), (2, 'Brad'), (3, 'Mary'), (4, 'Jennifer')) [v]

cmssoen2

cmssoen24#

select 1 a union all 
select T.* from (values (1),(2),(3),(4),(5)) as T;

a
---
1
1
2
3
4
5

小把戏,现在你有a栏了

ylamdve6

ylamdve65#

根据SQLite文档,
短语“Values(expr-list)”的意思与“SELECT EXPR-LIST”相同。短语“VALUES(EXPR-LIST-1),...,(EXPR-LIST-N)”的意思与“SELECT EXPR-LIST-1UNION ALL...UNION ALL SELECT EXPR-LIST-N”相同。
因此,您可以更改为:

SELECT T.a AS my_column_alias FROM (
 SELECT 1 as a
 UNION ALL
 SELECT 2 as a
 UNION ALL
 SELECT 3 as a
 UNION ALL
 SELECT 4 as a
 UNION ALL
 SELECT 5 as a
) as T;

那么“My_Column_Alias”就是您的列名/别名。

my_column_alias
---------------
1
2
3
4
5
ssgvzors

ssgvzors6#

下面是我使用的各种基于值的语法的集合。前两种方法对于单元测试特别方便,在单元测试中还可以使用基于内存的数据库示例。

选择取值

这只是返回值作为带有命名列的结果集。

SELECT
    column1 as Id,
    column2 as Name
FROM (VALUES
    (1, 'Alex'),
    (2, 'Brad'),
    (3, 'Mary'),
    (4, 'Jennifer')
)

公用表表达式(CTE)

与上面类似,还有一种CTE方法。这将为值选择的数据创建一个“名称”,这样您就可以在查询中的其他地方使用它,就像它是一个表一样。这允许您创建“迷你”表,然后您可以将其连接到最终输出中。(但在这里,我只创建了一个名为‘MyTable’的文件。)

WITH myTable(id, name) AS (
VALUES
    (1, 'Alex'),
    (2, 'Brad'),
    (3, 'Mary'),
    (4, 'Jennifer')
)
SELECT id, name
FROM myTable;

临时表(含完整性)

这与上面的CTE类似,但是命名结果在连接的整个生命周期内都存在(或者直到您手动删除它们,如果更早的话)。这就是为什么不同于上面两个可以毫无问题地运行的方法,如果表已经存在,那么这个方法就会失败,所以请确保首先“删除”它,或者清除它,然后用新数据重新填充它。

CREATE TEMP TABLE myTable (id Integer, name TEXT);

INSERT INTO myTable
VALUES 
    (1, 'Alex'),
    (2, 'Brad'),
    (3, 'Mary'),
    (4, 'Jennifer');

SELECT * FROM myTable;

啊哈!

相关问题