doris insert into和with as 合用

Apache Doris 的 INSERT INTO ... WITH AS(CTE)语法是支持的,但必须将 CTE 包裹在子查询中,或直接在 INSERT INTO ... SELECTSELECT 部分使用,并建议显式指定 WITH LABEL。‌‌

  • 标准写法 ‌:INSERT INTO target_table WITH LABEL label_name WITH cte_name AS (...) SELECT ... FROM cte_name;
  • 兼容写法 ‌(若上述报错):INSERT INTO target_table SELECT * FROM (WITH cte_name AS (...) SELECT ...) AS sub;
  • Doris 要求 ‌CTE 必须作为 SELECT 的一部分 ‌,不能独立于 INSERT INTO ... SELECT 之外使用;
  • ‌**生产环境建议显式指定 WITH LABEL**‌,避免自动生成标签冲突;
  • CTE 支持多层定义(如 WITH cte1 AS (...), cte2 AS (SELECT ... FROM cte1)),但整个查询需在 SELECT 子句内;
  • 若启用 enable_insert_strict = true(默认),数据格式错误会导致整个插入失败。‌‌

示例:

复制代码
INSERT INTO target_tbl WITH LABEL 'my_cte_label' WITH tmp AS (SELECT id, name FROM source_tbl WHERE status = 'active') SELECT id, UPPER(name) FROM tmp; ```‌‌:ml-citation{ref="11,12" appearance="aggregated" data="citationList"} 如遇语法错误,可改用子查询包裹 CTE: ```sql INSERT INTO target_tbl SELECT * FROM ( WITH cte AS (SELECT ... FROM ...) SELECT ... FROM cte ) AS sub;

sql

INSERT INTO target_tbl WITH LABEL 'my_cte_label' WITH tmp AS (SELECT id, name FROM source_tbl WHERE status = 'active') SELECT id, UPPER(name) FROM tmp; ```‌‌:ml-citation{ref="11,12" appearance="aggregated" data="citationList"}

如遇语法错误,可改用子查询包裹 CTE: ```sql INSERT INTO target_tbl SELECT * FROM ( WITH cte AS (SELECT ... FROM ...) SELECT ... FROM cte ) AS sub;

Doris 2.0+ 对 CTE 在 DML 中的支持更稳定,旧版本(如 1.x)可能存在限制,建议升级或测试验证。

具体案例:

sql 复制代码
INSERT INTO cdn.edge_client_area_bandwidth_hour SELECT * FROM (
    with crossSet as (SELECT
    t.time  as time,
    CASE WHEN (n & 1)   = 0 THEN CAST(t.productId AS STRING) ELSE 'all' END AS productId,
    CASE WHEN (n & 2)   = 0 THEN t.cp                       ELSE 'all' END AS cp,
    CASE WHEN (n & 4)   = 0 THEN t.domain                   ELSE 'all' END AS domain,
    CASE WHEN (n & 8)   = 0 THEN t.clientArea               ELSE 'all' END AS clientArea,
    CASE WHEN (n & 16)  = 0 THEN t.ipProtocol               ELSE 'all' END AS ipProtocol,
    CASE WHEN (n & 32)  = 0 THEN t.clientOperator           ELSE 'all' END AS clientOperator,
    CASE WHEN (n & 64)  = 0 THEN t.provider                 ELSE 'all' END AS provider,
    CASE WHEN (n & 128) = 0 THEN t.orderId                 ELSE 'all' END AS orderId,
    CASE WHEN (n & 256) = 0 THEN t.sourceCode               ELSE 'all' END AS sourceCode,
    t.value
FROM cdn.edge_client_area_bandwidth_fivemin t 
CROSS JOIN (SELECT number AS n FROM numbers("number"="512")) numbers WHERE t.time >= '2026-05-02 09:05:00' and t.time <= '2026-05-02 09:05:00'),
  sumTab as (select crossSet.time, crossSet.productId, crossSet.cp, crossSet.domain, crossSet.clientArea, crossSet.ipProtocol, crossSet.clientOperator, crossSet.provider, crossSet.orderId, crossSet.sourceCode, sum(value) as sumValue from crossSet group by crossSet.time, crossSet.productId, crossSet.cp, crossSet.domain, crossSet.clientArea, crossSet.ipProtocol, crossSet.clientOperator, crossSet.provider, crossSet.orderId, crossSet.sourceCode)
select "2026-05-02 09:00:00", "bandwidthMinBiz", sumTab.cp, sumTab.productId, sumTab.provider, sumTab.clientArea, sumTab.domain,  sumTab.clientOperator,  sumTab.ipProtocol,  sumTab.orderId, sumTab.sourceCode, max(sumValue) from sumTab group by sumTab.productId, sumTab.cp, sumTab.domain, sumTab.clientArea, sumTab.ipProtocol, sumTab.clientOperator, sumTab.provider, sumTab.orderId, sumTab.sourceCode
) AS sub;
相关推荐
ClouGence8 小时前
Oracle 数据同步为什么会出现数据不一致?长事务是常被忽略的原因
数据库·后端·oracle
飞将10 小时前
从零实现数据库(2)——HashIndex + IndexManager
数据库
Nturmoils1 天前
订单列表慢查询,先看 WHERE、ORDER BY 和 LIMIT
数据库
渣波1 天前
拒绝 SQL 焦虑!手把手带你用 NestJS + Prisma + DTO 写出“防弹”级后端代码
javascript·数据库·后端
倔强的石头_2 天前
KingbaseES 新版MySQL 兼容版体验:旧版迁移 + 功能实测
数据库
zzzzzz3103 天前
9K Star 炸裂开源!这个 C 语言写的代码知识图谱,把 Linux 内核索引压缩到了 3 分钟
linux·服务器·sql
倔强的石头_5 天前
《Kingbase护城河》——数据库存储空间全景探测与精细化瘦身实战
数据库
云技纵横5 天前
唯一索引 INSERT 死锁实战:5 秒复现交叉插入的 S 锁循环等待
sql·mysql
冬奇Lab6 天前
每日一个开源项目(第134篇):Zvec - 阿里开源的嵌入式向量数据库,向量搜索界的 SQLite
数据库·人工智能·llm
ClouGence6 天前
Oracle CDC 架构优化:从主库直连到 DataGuard 备库同步
数据库·后端·oracle