SQLazy: 按订单 SKU 条件分配仓库

问题描述

订单明细表记录了每笔订单的 ORDER_NUMBER、SKU 和 WEBSITE。现在需要按整单判断:如果同一订单中存在 SKU 为 10000 或 20000 的行,或者网站不是 EU SITE,则整单所有行分配 WAREHOUSE 1;否则分配 WAREHOUSE 2。新增字段 FULFILLED_BY。

源数据

|--------------|-------|---------|
| ORDER_NUMBER | SKU | WEBSITE |
| 10001 | 10000 | EU SITE |
| 10001 | 15123 | EU SITE |
| 10002 | 20000 | EU SITE |
| 10002 | 28467 | EU SITE |
| 10003 | 15123 | EU SITE |
| 10003 | 15124 | EU SITE |
| 10004 | 10000 | US SITE |
| 10005 | 15123 | US SITE |
| 10006 | 10000 | EU SITE |
| 10007 | 28467 | EU SITE |

期望结果

|--------------|-------|---------|--------------|
| ORDER_NUMBER | SKU | WEBSITE | FULFILLED_BY |
| 10001 | 10000 | EU SITE | WAREHOUSE 1 |
| 10001 | 15123 | EU SITE | WAREHOUSE 1 |
| 10002 | 20000 | EU SITE | WAREHOUSE 1 |
| 10002 | 28467 | EU SITE | WAREHOUSE 1 |
| 10003 | 15123 | EU SITE | WAREHOUSE 2 |
| 10003 | 15124 | EU SITE | WAREHOUSE 2 |
| 10004 | 10000 | US SITE | WAREHOUSE 1 |
| 10005 | 15123 | US SITE | WAREHOUSE 1 |
| 10006 | 10000 | EU SITE | WAREHOUSE 1 |
| 10007 | 28467 | EU SITE | WAREHOUSE 2 |

以几个有代表性的订单为例:

订单 10001、10002:包含特殊 SKU 10000 或 20000,整单分配 WAREHOUSE 1。

订单 10003:均为 EU SITE 且不含特殊 SKU,整单分配 WAREHOUSE 2。

订单 10004、10005:网站为 US SITE(非 EU),整单分配 WAREHOUSE 1。订单 10007:单行订单,非特殊 SKU,EU 站点,分配 WAREHOUSE 2。

SQLazy 分步实现

**核心思路:**按订单分组,用 compute 的 max 聚合判断订单中是否存在特殊 SKU,再根据聚合结果和 WEBSITE 条件,在同一个 compute 中计算出整单的 FULFILLED_BY。

|------|-----------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Name | Anchor | Statement |
| t1 | tb_detail | compute if ((10000,20000 contain SKU)then 1 else 0) max as order_has_special; if (order_has_special = 1 or WEBSITE <> "EU SITE" then "WAREHOUSE 1" else "WAREHOUSE 2") as FULFILLED_BY; partition ORDER_NUMBER |
| | | derive ORDER_NUMBER, SKU, WEBSITE, FULFILLED_BY |

下面逐一解释这些步骤。

第 1 步:按订单分组计算分配仓库(核心)

compute if ((10000,20000 contain SKU)then 1 else 0) max as order_has_special; if (order_has_special = 1 or WEBSITE <> "EU SITE" then "WAREHOUSE 1" else "WAREHOUSE 2") as FULFILLED_BY; partition ORDER_NUMBER

这是核心的一步。一个 compute 语句中计算了两个字段:order_has_special,对订单内的每一行判断 SKU 是否在列表 10000,20000 中,用 contain 做集合成员检查,再以 max 聚合到订单级别------只要订单中任意一行命中,max 结果就是 1。 FULFILLED_BY:利用上一步的聚合结果,当 order_has_special=1 或 WEBSITE 不是 EU SITE 时分配 WAREHOUSE 1,否则分配 WAREHOUSE 2。partition ORDER_NUMBER 确保聚合和计算都在订单级别。

第 2 步:选择最终输出列

derive ORDER_NUMBER, SKU, WEBSITE, FULFILLED_BY

用 derive 保留需要的四列,去掉辅助字段 order_has_special,输出最终结果。

编译生成 SQL

确认上述步骤后,SQLazy 编译器自动生成原生 SQL(Snowflake 语法):

复制代码
WITH tb_detail_1 AS (
    SELECT ORDER_NUMBER, SKU, WEBSITE
        , MAX(CASE
            WHEN SKU IN (10000, 20000) THEN 1
            ELSE 0
        END) OVER (PARTITION BY ORDER_NUMBER) AS order_has_special
    FROM tb_detail
),
t1 AS (
    SELECT ORDER_NUMBER, SKU, WEBSITE, order_has_special
        , CASE
            WHEN order_has_special = 1
                OR WEBSITE <> 'EU SITE'
            THEN 'WAREHOUSE 1'
            ELSE 'WAREHOUSE 2'
        END AS FULFILLED_BY
    FROM tb_detail_1
)
SELECT ORDER_NUMBER, SKU, WEBSITE, FULFILLED_BY
FROM t1

SQLazy 让你用业务语言描述逻辑,而不是用 SQL 语法写嵌套查询。这个例子用 compute 语句完成 "先按订单聚合出标记、再基于标记分配" 的两层逻辑,无需像 SQL 那样先写一个 CTE 做 MAX(CASE WHEN ... IN ...) OVER 窗口聚合,再写另一个 CTE 做 CASE WHEN 判断。compute 的 partition 子句将 "订单级计算" 的语义直接表达出来,contain 函数让 "集合成员检查" 像日常语言一样可读。分步计算让每一步的中间结果都可独立验证,降低了整体逻辑的出错概率。

相关推荐
做运维的阿瑞4 小时前
SQL 面试高频:用户、商品、订单三表查询全解析
数据库·sql·mysql
做运维的阿瑞9 小时前
MYSQL从语义到执行计划:UNION、EXISTS、IN 的深度辨析
数据库·sql·mysql
Moshow郑锴10 小时前
sql-pipeline - 基于PostgreSQL的SQL健康检查与发布编排平台
java·sql
Elastic 中国社区官方博客1 天前
错误最多的服务运行正常:使用 ES|QL 从日志进行根因分析
大数据·运维·数据库·sql·elasticsearch·搜索引擎·全文检索
Seraphina361 天前
DVWA(SQL Injection-High,XSS Reflected-Medium,XSS Stored-Medium)
数据库·经验分享·sql·网络安全·xss
2501_933670791 天前
2027风控策略岗秋招准备:SQL、Excel、建模的优先级与项目路径
人工智能·sql·excel
其实防守也摸鱼1 天前
网安自测题:掌握核心知识点的实用练习
linux·运维·服务器·前端·数据库·sql·xss
Shadow(⊙o⊙)1 天前
MySQL C/C++链接MySQL使用
数据库·sql·mysql
Shadow(⊙o⊙)1 天前
mysql为创建普通用户并创建库赋权
数据库·sql·mysql
Seraphina362 天前
SQLI-labs(一)黑盒全流程
sql·安全·web安全