使用 SQL 清理数据 - 取列差异
Clean Data Using SQL - Take Column Difference
我在SQL中有如下数据:
实际Table
+-------------+--------+------+
| Id | Weight | Type |
+-------------+--------+------+
| 00011223344 | 35 | A |
| 00011223344 | 10 | A |
| 12311223344 | 100 | B |
| 00034343434 | 25 | A |
| 00034343434 | 25 | A |
| 99934343434 | 200 | C |
| 88855667788 | 100 | D |
+-------------+--------+------+
列 ID
的长度始终为 11,数据类型为 varchar。我需要从上面的 table 创建一个列 Actual Weight
和 Actual ID
。
Actual Id
依赖于列 ID
。如果 ID 以 000
开头,那么我们需要从 ID
列中找到不以 000
开头但之后的字符(即从右边开始的 8 个字符)相似的 ID。匹配的 ID 为 Actual Id
。例如,如果我们查看前 3 个 ID,前 2 个以 000
开头,另一个不以 000
开头且包含右起类似 8 个字符的 ID 可以在第 3 行中找到,即 12311223344
因此在派生列 Actual ID
中,前两行将 Actual Id
作为 12311223344
.
Actual Weight
取决于 2 列 ID
和 Weight
中的值。如果对于任何不以 000
开头但包含另一个以 000
开头的条目的 Id
,我们需要根据上述条件对列 Id
进行分组。然后我们需要为不以 000
开头的 Id
重新计算 Weight
,方法是将所有以 000
开头的权重相加,并与不以 [= 开头的权重相加=18=].
例如,如果我们查看前 3 行,在第 3 行中我们有 Id
以 123
开头并且具有从右边开始有 8 位数字的条目,除了它们以 [= 开头18=] 而不是 123
(即第 1 行和第 2 行)。对于以 000
开头的情况,Actual Weight
将类似于 Weight
,但对于以 123
开头的情况,Actual Weight
将是 100-(35+10)
我正在寻找可以创建这 2 个派生列而无需创建任何其他 table/view.
的查询
期望输出
+-------------+-------------+--------+---------------+------+
| Id | Actual ID | Weight | Actual Weight | Type |
+-------------+-------------+--------+---------------+------+
| 00011223344 | 12311223344 | 35 | 35 | A |
| 00011223344 | 12311223344 | 10 | 10 | A |
| 12311223344 | 12311223344 | 100 | 55 | B |
| 00034343434 | 99934343434 | 25 | 25 | A |
| 00034343434 | 99934343434 | 25 | 25 | A |
| 99934343434 | 99934343434 | 200 | 150 | C |
| 88855667788 | 88855667788 | 100 | 100 | D |
+-------------+-------------+--------+---------------+------+
嗯嗯。 . .如果我关注这个:
select t.*,
(case when id like '000%' then weight
else weight - sum(case when id like '000%' then weight else 0 end) over (partition by actual_id)
end) as actual_weight
from (select t.*,
max(id) over (partition by stuff(id, 1, 3, '')) as actual_id
from t
) t;
Here 是一个 db<>fiddle.
我在SQL中有如下数据:
实际Table
+-------------+--------+------+
| Id | Weight | Type |
+-------------+--------+------+
| 00011223344 | 35 | A |
| 00011223344 | 10 | A |
| 12311223344 | 100 | B |
| 00034343434 | 25 | A |
| 00034343434 | 25 | A |
| 99934343434 | 200 | C |
| 88855667788 | 100 | D |
+-------------+--------+------+
列 ID
的长度始终为 11,数据类型为 varchar。我需要从上面的 table 创建一个列 Actual Weight
和 Actual ID
。
Actual Id
依赖于列 ID
。如果 ID 以 000
开头,那么我们需要从 ID
列中找到不以 000
开头但之后的字符(即从右边开始的 8 个字符)相似的 ID。匹配的 ID 为 Actual Id
。例如,如果我们查看前 3 个 ID,前 2 个以 000
开头,另一个不以 000
开头且包含右起类似 8 个字符的 ID 可以在第 3 行中找到,即 12311223344
因此在派生列 Actual ID
中,前两行将 Actual Id
作为 12311223344
.
Actual Weight
取决于 2 列 ID
和 Weight
中的值。如果对于任何不以 000
开头但包含另一个以 000
开头的条目的 Id
,我们需要根据上述条件对列 Id
进行分组。然后我们需要为不以 000
开头的 Id
重新计算 Weight
,方法是将所有以 000
开头的权重相加,并与不以 [= 开头的权重相加=18=].
例如,如果我们查看前 3 行,在第 3 行中我们有 Id
以 123
开头并且具有从右边开始有 8 位数字的条目,除了它们以 [= 开头18=] 而不是 123
(即第 1 行和第 2 行)。对于以 000
开头的情况,Actual Weight
将类似于 Weight
,但对于以 123
开头的情况,Actual Weight
将是 100-(35+10)
我正在寻找可以创建这 2 个派生列而无需创建任何其他 table/view.
的查询期望输出
+-------------+-------------+--------+---------------+------+
| Id | Actual ID | Weight | Actual Weight | Type |
+-------------+-------------+--------+---------------+------+
| 00011223344 | 12311223344 | 35 | 35 | A |
| 00011223344 | 12311223344 | 10 | 10 | A |
| 12311223344 | 12311223344 | 100 | 55 | B |
| 00034343434 | 99934343434 | 25 | 25 | A |
| 00034343434 | 99934343434 | 25 | 25 | A |
| 99934343434 | 99934343434 | 200 | 150 | C |
| 88855667788 | 88855667788 | 100 | 100 | D |
+-------------+-------------+--------+---------------+------+
嗯嗯。 . .如果我关注这个:
select t.*,
(case when id like '000%' then weight
else weight - sum(case when id like '000%' then weight else 0 end) over (partition by actual_id)
end) as actual_weight
from (select t.*,
max(id) over (partition by stuff(id, 1, 3, '')) as actual_id
from t
) t;
Here 是一个 db<>fiddle.