sql - 您能否成功地将多个条件嵌套在 partition by 语句中?
问题描述
我在 Fiddle 中构建了这个示例表:https ://www.db-fiddle.com/f/pu1PkjzKCM9VRciznkJc4L/7
我正在为帐号和序列号重新标记地区。您可以看到我尝试更改数据并添加具有正确区域的新列的表架构和查询。问题是我的结果,你会在最后看到。我想找到一种方法首先通过serial_number,我确定serial_numbers 是跟踪区域的最佳方法,然后在serial_numbers 为空时添加正确的区域名称时的acct_num。
但是,虽然我的程序主要用于此目的。当有一个 acct_num 并且没有 serial_number 时,它不会只是抛出它找到的最后一个“正确”区域。我需要这个程序来做到这一点。我在想也许是一个嵌套的case语句?我曾尝试在先前存在的 CASE 和 PARTITION BY 语句中执行此操作,但我一直没有成功,它一直抛出语法错误。
我在想...(PARTITION BY WHEN serial_number='NULL' THEN acct_num ELSE serial_number),但这总是会引发错误。
任何帮助表示赞赏!
SQL 架构
'''
CREATE TABLE t (
"row" INTEGER,
"acct_num" TEXT,
"serial_number" TEXT,
"site_address" TEXT,
"city" TEXT,
"territory_name" TEXT
);
INSERT INTO t
("row", "acct_num", "serial_number", "site_address", "city", "territory_name")
VALUES
('1', '049403', 'TH-530', '344 Clinton Str', 'Metropolis', 'Central'),
('2', '049403', 'TH-530', '344 Clinton Str', 'Metropolis', 'Central'),
('3', '049206', 'GO-650', '1007 Mountain Dr', 'Gotham City', 'Gotham City'),
('4', '049206', 'GO-650', '1007 Mountain Dr', 'Gotham City', 'Gotham City'),
('5', '049206', 'GO-650', 'NULL', 'NULL', 'N/A'),
('6', '049206', 'TJO-560', 'NULL', 'NULL', 'NULL'),
('7', '049291', 'SM-708', '1938 Sullivan Pl', 'Smallville', 'No Territory'),
('8', '049293', 'TH-533', '700 Hamilton Str', 'Central City', 'Central'),
('9', '049396', 'AL-670', '800 Ellsmore Way', 'Alberty Township', 'South'),
('10', '049396', 'KILO-680', '600 Nukem Drive', 'Duke City', 'Southeast'),
('11', '049396', 'JALO-605', '5806 London Way', 'Hampshire', 'Northeast'),
('12', '049396', 'NULL', 'NULL', 'NULL', 'No Territory');
'''
SQL查询
'''
select row,
acct_num,
serial_number,
site_address,
MAX(
CASE
WHEN territory_name <> 'N/A' AND territory_name <> 'No Territory'
THEN territory_name
WHEN serial_number = 'NULL'
THEN territory_name
END)
over (PARTITION BY serial_number) as imputed_place
from t
order by row
'''
SQL查询结果
| row | acct_num | serial_number | site_address | imputed_place
| ----|----------|----------------|-----------------|---------------
| 1 | 049403 | TH-530 | 344 Clinton Str | Central
| 2 | 049403 | TH-530 | 344 Clinton Str | Central
| 3 | 049206 | GO-650 | 1007 Mountain Dr| Gotham City
| 4 | 049206 | GO-650 | 1007 Mountain Dr| Gotham City
| 5 | 049206 | GO-650 | NULL | Gotham City
| 6 | 049206 | TJO-560 | NULL | NULL
| 7 | 049291 | SM-708 | 1938 Sullivan Pl| null
| 8 | 049293 | TH-533 | 700 Hamilton Str| Central
| 9 | 049396 | AL-670 | 800 Ellsmore Way| South
| 10 | 049396 | KILO-680 | 600 Nukem Drive | Southeast
| 11 | 049396 | JALO-605 | 5806 London Way | Northeast
| 12 | 049396 | NULL | NULL | No Territory <- should be Northeast!!!
'''
DB Fiddle – 由英国 Status200 用 ♥ 制作。使用条款 • 隐私/Cookie 政策 • Status200 Ltd © 2018
解决方案
我试图重新创建您的结果(包括第 12 行),列行是解决方案/数据的一部分吗?
我采用的方法是按序列号创建有效值的映射表,因此键+值必须是唯一的,否则我们将结果从 12 行分解为...更多!当我查看不是这种情况的帐号时,这对序列号很有效。没有唯一的映射,确定第 12 行应该是“东北”的规则是什么?
如果它基于行,那么结果很容易,我将在下面提供解决方案,
with map_by_serial_no as (
select distinct "serial_number"
, "territory_name"
from t
where "serial_number" <> 'NULL'
and "territory_name" <> 'N/A'
and "territory_name" <> 'NULL'
)
select t."row"
, t."acct_num"
, t."serial_number"
, t."site_address"
, t."city"
, t."territory_name"
, case when t."serial_number" = 'NULL' then lag(t."territory_name") over (order by "row")
when t."territory_name" in ('NULL', 'No Territory', 'N/A') then u."territory_name"
else t."territory_name" end as imputed_territory
from t
left join map_by_serial_no u
on t."serial_number" = u."serial_number"
order by "row";
但是请注意,NULL 应该是没有值,而在此示例中它是带引号的字符串。
推荐阅读
- blazor - 为什么 Blazor API 调用停止工作,直到我重命名我的 API 方法
- javascript - 意外令牌导出 firebase-app.js:1590
- java - 如何使用 Java Swing 渲染视频?
- flutter - Flutter:复杂的 Shader Mask 渐变效果
- python - 代码中的错误。Scikit 图像,Spyder
- go - 如何以 Go 语法在模板中输出地图?
- apache-spark - “SparkSession”对象没有属性“textFile”
- javascript - 如何在javascript中解析包含数组的任意数学表达式
- django - 如何在 Django Rest Framework 中自定义 ManyToMany 字段的更新方法
- flutter - 如何创建一个可以被多个区域使用的 Widget 监听的单例 Stream