【问题标题】:Can you nest a number of conditions in a partition by statement successfully?您能否成功地将多个条件嵌套在 partition by 语句中?
【发布时间】:2021-11-14 10:38:07
【问题描述】:

我在 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

【问题讨论】:

  • 感谢您创建示例数据并共享查询及其结果。但是你能分享一下想要的结果是什么而不是这些吗?
  • 您好 Felipe,SQL 查询结果表中有一条注释说“没有领土

标签: sql snowflake-cloud-data-platform domo


【解决方案1】:

我尝试重新创建您的结果(包括第 12 行),列行是解决方案/数据的一部分吗?

我采用的方法是按序列号创建有效值的映射表,因此键+值必须是唯一的,否则我们会将结果从 12 行分解为...更多!当我查看不是这种情况的帐号时,这对序列号很有效。没有唯一的映射,是什么规则决定第 12 行应该是 'Northeast'?

如果它是基于行的,那么结果很简单,我将在下面提供解决方案,

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 应该是没有值,而在这个示例中它是一个带引号的字符串。

【讨论】:

  • 这太棒了!但是,您是对的,当同一帐号中有多个“无领土”行时,它就会崩溃。您的解决方案只会更新一行,但不会超过一行。我们只是试图获取该领土名称并将其应用于所有无领土标签。至于它背后的逻辑,这是最方便的解决方案。 :-P 我用这种可能的情况更新了小提琴。 :-/
  • 是的,所以数据建模的方式,基于序列号的分配很容易,但帐号很弱;要么模型需要改进,要么规则必须改变
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-27
  • 1970-01-01
  • 2012-02-17
  • 1970-01-01
  • 2019-04-10
  • 2021-10-29
  • 2019-12-31
相关资源
最近更新 更多