SQL 将多个 CTE table 导出到新的 table
SQL export multiple CTE tables to a new table
我在查询中创建了两个 CTE 表,它们在 1 天内以不同级别查看我的数据。添加了大量数据,一切运行顺利。如果我将 SELECT * FROM level1_cte
添加到末尾,它将产生正确的输出。
Q1:
为什么我不能一次查询所有的 cte 表?他们互不依赖。
WITH level1
AS
(
SELECT [order] FROM test
),
level2
([route], tag)
AS (
SELECT
[route],
tag
FROM test
)
SELECT * FROM level1
SELECT * FROM level2
这会产生错误,我需要注释掉其中一个表才能只查看一个。
Q2:
我想将这两个表中的数据写入三个永久表(level1,level2)。这可能吗,或者我是否需要从该查询中复制和创建两个不同的过程?
DMBS 是 SQL 服务器
数据:
create table test (
"date" date,
"order" varchar(10),
route varchar(10),
tag varchar(10),
test varchar(10))
insert into test values
('2022-01-01','A','AB','NA','AB'),
('2022-01-01','A','AB','NA','AB'),
('2022-01-01','A','AB','NA','AB'),
('2022-01-01','B','BB','NA','AB'),
('2022-01-01','B','BB','NA','AB'),
('2022-01-01','B','BB','this','AB')
Why can't I query all of my cte tables at once? They don't depend on each others.
考虑这些事情:
- 虽然单个查询可以有多个 CTE,a single CTE cannot be shared by multiple queries。
- 我同意这很烦人。
- 每个 top-level
SELECT
语句代表一个完全独立的查询。
- (令人困惑的是,CTE (
WITH x AS ( ... )
) 位于 之前 SELECT
关键字,但它仍然是单个查询。
- 因此,您的
SELECT * FROM level1 SELECT * FROM level2
语句是 两个单独的查询 。
- 只有 第一个 查询 (
SELECT * FROM level1
) 可以访问之前定义的 level1
和 level2
CTE。
- This is why you should always use a terminating semicolon这样你就可以not-only直观的看到每条语句和查询的句法边界,也可以防止你以后再犯这种错误。
- 所以它的格式应该是:
------------------
-- Query 1:
------------------
WITH level1 AS (
SELECT [order] FROM test
),
level2 AS AS (
SELECT [route], [tag] FROM test
)
SELECT * FROM level1;
------------------
-- Query 2 (which is *entirely separate* from Query 1 above):
------------------
SELECT * FROM level2; /* <-- Error: The `level2` CTE isn't in-scope! */
- 您 可以 通过使用
UNION ALL
连接它们的结果将两个或多个 SELECT
查询合并为一个,但是您只能对使用相同 column-design,但是您的两个 SELECT
语句具有不同的列 ([order]
) 与 ([route]
和 [tag]
),因此将它们连接起来是没有意义的 as-is.
但是如果你确实想连接它们,使用NULL
作为它们缺失列的数据,那么这样做:
WITH level1 AS (
SELECT
[order]
FROM
test
),
level2 AS AS (
SELECT
[route],
[tag]
FROM
test
)
SELECT
NULL AS [route],
NULL AS [tag],
[order]
FROM
level1
UNION ALL
SELECT
[route],
[tag]
NULL AS [order]
FROM
level2; /* <-- Note the semicolon. */
我在查询中创建了两个 CTE 表,它们在 1 天内以不同级别查看我的数据。添加了大量数据,一切运行顺利。如果我将 SELECT * FROM level1_cte
添加到末尾,它将产生正确的输出。
Q1: 为什么我不能一次查询所有的 cte 表?他们互不依赖。
WITH level1
AS
(
SELECT [order] FROM test
),
level2
([route], tag)
AS (
SELECT
[route],
tag
FROM test
)
SELECT * FROM level1
SELECT * FROM level2
这会产生错误,我需要注释掉其中一个表才能只查看一个。
Q2: 我想将这两个表中的数据写入三个永久表(level1,level2)。这可能吗,或者我是否需要从该查询中复制和创建两个不同的过程?
DMBS 是 SQL 服务器
数据:
create table test (
"date" date,
"order" varchar(10),
route varchar(10),
tag varchar(10),
test varchar(10))
insert into test values
('2022-01-01','A','AB','NA','AB'),
('2022-01-01','A','AB','NA','AB'),
('2022-01-01','A','AB','NA','AB'),
('2022-01-01','B','BB','NA','AB'),
('2022-01-01','B','BB','NA','AB'),
('2022-01-01','B','BB','this','AB')
Why can't I query all of my cte tables at once? They don't depend on each others.
考虑这些事情:
- 虽然单个查询可以有多个 CTE,a single CTE cannot be shared by multiple queries。
- 我同意这很烦人。
- 每个 top-level
SELECT
语句代表一个完全独立的查询。- (令人困惑的是,CTE (
WITH x AS ( ... )
) 位于 之前SELECT
关键字,但它仍然是单个查询。 - 因此,您的
SELECT * FROM level1 SELECT * FROM level2
语句是 两个单独的查询 。- 只有 第一个 查询 (
SELECT * FROM level1
) 可以访问之前定义的level1
和level2
CTE。
- 只有 第一个 查询 (
- This is why you should always use a terminating semicolon这样你就可以not-only直观的看到每条语句和查询的句法边界,也可以防止你以后再犯这种错误。
- 所以它的格式应该是:
------------------ -- Query 1: ------------------ WITH level1 AS ( SELECT [order] FROM test ), level2 AS AS ( SELECT [route], [tag] FROM test ) SELECT * FROM level1; ------------------ -- Query 2 (which is *entirely separate* from Query 1 above): ------------------ SELECT * FROM level2; /* <-- Error: The `level2` CTE isn't in-scope! */
- 所以它的格式应该是:
- (令人困惑的是,CTE (
- 您 可以 通过使用
UNION ALL
连接它们的结果将两个或多个SELECT
查询合并为一个,但是您只能对使用相同 column-design,但是您的两个SELECT
语句具有不同的列 ([order]
) 与 ([route]
和[tag]
),因此将它们连接起来是没有意义的 as-is.
但是如果你确实想连接它们,使用NULL
作为它们缺失列的数据,那么这样做:
WITH level1 AS (
SELECT
[order]
FROM
test
),
level2 AS AS (
SELECT
[route],
[tag]
FROM
test
)
SELECT
NULL AS [route],
NULL AS [tag],
[order]
FROM
level1
UNION ALL
SELECT
[route],
[tag]
NULL AS [order]
FROM
level2; /* <-- Note the semicolon. */