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 函数让 "集合成员检查" 像日常语言一样可读。分步计算让每一步的中间结果都可独立验证,降低了整体逻辑的出错概率。

相关推荐
猫咪很可爱17 小时前
MySQL 视图与只读用户:安全查询的完整实践指南
数据库·sql·mysql
三垣网安19 小时前
某某大学心理健康教育平台弱口令及SQL注入漏洞
数据库·sql
泡海椒1 天前
JQuick-SQL “数据源 SPI”辨析:应用适配器与 Function SPI 的正确边界
数据库·驱动开发·sql
泡海椒1 天前
JQuick-SQL 逻辑数据仓库:以注册数据集构建轻量分析层
数据库·数据仓库·sql
泡海椒1 天前
JQuick-SQL JQuickTable 模型:XML 动态 SQL 的表封装边界
xml·数据库·sql
geovindu1 天前
sql:SQL Pagination and Limiting Results using PorstgreSQL 18.0
大数据·数据仓库·sql·postgresql·数据库开发·数据库架构·1024程序员节
EnCi Zheng2 天前
PostgreSQL 实战指南:安装配置、数据类型、索引选型、MVCC 事务与高可用备份全解析
数据库·sql·postgresql·索引·1024程序员节
泡海椒2 天前
JQuick-SQL REST API 数据接入:应用层调用接口后注册分析表
数据库·sql·1024程序员节
handsome_sai2 天前
mysql索引
sql·1024程序员节
莫叫石榴姐2 天前
半导体业务数仓建模: Lot、Wafer、Die、Recipe、OEE、YMS 建模要点
数据仓库·sql·面试·职场和发展·矩阵·1024程序员节