SQL - 计算如果 "category bucket" 被移除,有多少唯一 ID 会成为 w/o 一个类别
SQL - Count how many unique IDs would be w/o a category if "category bucket" was removed
我正在使用 Snowflake 来解决这个 SQL 问题,如果有任何独特的功能我可以使用,请帮助我!
我有一个包含唯一 ID 的数据集,其他不重要的属性,然后是每个唯一 ID 可能属于的类别列表 (~22)(如果它在类别中则用 1 表示,如果它在类别中则用 0 表示)如果没有。)
我想弄清楚如何写一些东西,我可以在其中查看是否跨所有类别,是否删除了某个类别,如果任何唯一 ID 将没有任何类别,并计算有多少唯一 ID 会然后做总共有多少 id 将被留在类别中。
下面的示例是唯一 ID Jshshsv,它仅在 CatAA 中,但 ID Hairbdb 在 CatY 和 CatAA 中。如果 CatAA 被删除,会有多少 ID 没有类别?
UniqueID
Sum across Categories
CatX
CatY
CatZ
CatAA
Hairbdb
2
0
1
0
1
Jshshsv
1
0
0
0
1
出于某种原因,我无法弄清楚如何在 sql 中使用如此多的类别桶以可管理的方式执行此操作。任何提示或尝试的事情将不胜感激。
所以如果你的数据是成对的,有重复
身份证|猫
--|--
Hairbdb|猫Y
Hairbdb|猫Y
Hairbdb|CatAA
Jshshsv|CatAA
Jshshsv|CatAA
可以使用以下SQL来查找类别是ID的单个匹配项。
WITH data AS (
SELECT * FROM VALUES
('Hairbdb','CatY'),
('Hairbdb','CatAA'),
('Jshshsv','CatAA')
v(id, cat)
), dist_data AS (
SELECT DISTINCT id, cat FROM data
), cat_counts AS (
SELECT id, count(distinct cat) c_cat
FROM data
GROUP BY 1
HAVING c_cat = 1
)
SELECT a.cat, a.id
FROM dist_data AS a
JOIN cat_counts AS b
ON b.id = a.id;
这是可行的,因为你首先计算每个 id,id 属于多少类别,然后你将不同的数据与 id 只在一只猫中的数据相结合,会给你 id & cat
CAT
ID
CatAA
Jshshsv
如果你的数据是宽格式的(比如你如何呈现它),你可以像这样通过 UNPIVOT 把它变成我的表格:
WITH data AS (
SELECT * FROM VALUES
('Hairbdb',0,1,0,1),
('Jshshsv',0,0,0,1)
v(id, catx, caty, catz, cataa )
)
SELECT id, cat from data unpivot(catv for cat in (catx, caty, catz, cataa))
WHERE catv = 1;
给予:
ID
CAT
Hairbdb
CATY
Hairbdb
CATAA
Jshshsv
CATAA
但是如果它在您的表单中并且删除了重复项,您可以只使用 WHERE 子句:
WITH data AS (
SELECT * from values
('Hairbdb', 0, 1, 0, 1),
('Jshshsv', 0, 0, 0, 1)
v(UniqueID, CatX,CatY,CatZ, CatAA)
)
SELECT UniqueID,
CatX+CatY+CatZ+CatAA as "Sum across Categories",
CatX,
CatY,
CatZ,
CatAA
FROM data
WHERE "Sum across Categories" = 1;
所以另一种变体,如果每个 id 有很多行,并且整个集合中的类别分配不相同,则可以使用 COUNT_IF 和大于 0 的测试将数据转换为a in any,然后使用HAVING子句过滤掉那些在许多列中的那些
WITH data AS (
SELECT * FROM VALUES
('Hairbdb',0,1,0,1),
('Hairbdb',1,1,0,1),
('Hairbdb',0,1,1,1),
('Jshshsv',0,0,0,1),
('Jshshsv',0,0,0,1)
v(id, catx, caty, catz, cataa )
)
SELECT id,
COUNT_IF(catx=1)>0 AS catx_a,
COUNT_IF(caty=1)>0 AS caty_a,
COUNT_IF(catz=1)>0 AS catz_a,
COUNT_IF(cataa=1)>0 AS cataa_a
FROM data
GROUP BY 1
HAVING catx_a::int + caty_a::int + catz_a::int + cataa_a::int = 1;
如果您将类别存储在列中(虽然不是一个好的设计),您可以试试这个。
SELECT UniqueID , sum(CatX+CatY+CatZ+CatAA) over (partition by UniqueID) as "Sum across Categories",
CatX, CatY, CatZ, CatAA FROM (
SELECT 'Hairbdb' as UniqueID, 0 as CatX, 1 as CatY, 0 as CatZ, 1 as CatAA from dual
UNION ALL
SELECT 'Jshshsv', 0,0,0,1 from dual
);
我正在使用 Snowflake 来解决这个 SQL 问题,如果有任何独特的功能我可以使用,请帮助我!
我有一个包含唯一 ID 的数据集,其他不重要的属性,然后是每个唯一 ID 可能属于的类别列表 (~22)(如果它在类别中则用 1 表示,如果它在类别中则用 0 表示)如果没有。)
我想弄清楚如何写一些东西,我可以在其中查看是否跨所有类别,是否删除了某个类别,如果任何唯一 ID 将没有任何类别,并计算有多少唯一 ID 会然后做总共有多少 id 将被留在类别中。
下面的示例是唯一 ID Jshshsv,它仅在 CatAA 中,但 ID Hairbdb 在 CatY 和 CatAA 中。如果 CatAA 被删除,会有多少 ID 没有类别?
UniqueID | Sum across Categories | CatX | CatY | CatZ | CatAA |
---|---|---|---|---|---|
Hairbdb | 2 | 0 | 1 | 0 | 1 |
Jshshsv | 1 | 0 | 0 | 0 | 1 |
出于某种原因,我无法弄清楚如何在 sql 中使用如此多的类别桶以可管理的方式执行此操作。任何提示或尝试的事情将不胜感激。
所以如果你的数据是成对的,有重复 身份证|猫 --|-- Hairbdb|猫Y Hairbdb|猫Y Hairbdb|CatAA Jshshsv|CatAA Jshshsv|CatAA
可以使用以下SQL来查找类别是ID的单个匹配项。
WITH data AS (
SELECT * FROM VALUES
('Hairbdb','CatY'),
('Hairbdb','CatAA'),
('Jshshsv','CatAA')
v(id, cat)
), dist_data AS (
SELECT DISTINCT id, cat FROM data
), cat_counts AS (
SELECT id, count(distinct cat) c_cat
FROM data
GROUP BY 1
HAVING c_cat = 1
)
SELECT a.cat, a.id
FROM dist_data AS a
JOIN cat_counts AS b
ON b.id = a.id;
这是可行的,因为你首先计算每个 id,id 属于多少类别,然后你将不同的数据与 id 只在一只猫中的数据相结合,会给你 id & cat
CAT | ID |
---|---|
CatAA | Jshshsv |
如果你的数据是宽格式的(比如你如何呈现它),你可以像这样通过 UNPIVOT 把它变成我的表格:
WITH data AS (
SELECT * FROM VALUES
('Hairbdb',0,1,0,1),
('Jshshsv',0,0,0,1)
v(id, catx, caty, catz, cataa )
)
SELECT id, cat from data unpivot(catv for cat in (catx, caty, catz, cataa))
WHERE catv = 1;
给予:
ID | CAT |
---|---|
Hairbdb | CATY |
Hairbdb | CATAA |
Jshshsv | CATAA |
但是如果它在您的表单中并且删除了重复项,您可以只使用 WHERE 子句:
WITH data AS (
SELECT * from values
('Hairbdb', 0, 1, 0, 1),
('Jshshsv', 0, 0, 0, 1)
v(UniqueID, CatX,CatY,CatZ, CatAA)
)
SELECT UniqueID,
CatX+CatY+CatZ+CatAA as "Sum across Categories",
CatX,
CatY,
CatZ,
CatAA
FROM data
WHERE "Sum across Categories" = 1;
所以另一种变体,如果每个 id 有很多行,并且整个集合中的类别分配不相同,则可以使用 COUNT_IF 和大于 0 的测试将数据转换为a in any,然后使用HAVING子句过滤掉那些在许多列中的那些
WITH data AS (
SELECT * FROM VALUES
('Hairbdb',0,1,0,1),
('Hairbdb',1,1,0,1),
('Hairbdb',0,1,1,1),
('Jshshsv',0,0,0,1),
('Jshshsv',0,0,0,1)
v(id, catx, caty, catz, cataa )
)
SELECT id,
COUNT_IF(catx=1)>0 AS catx_a,
COUNT_IF(caty=1)>0 AS caty_a,
COUNT_IF(catz=1)>0 AS catz_a,
COUNT_IF(cataa=1)>0 AS cataa_a
FROM data
GROUP BY 1
HAVING catx_a::int + caty_a::int + catz_a::int + cataa_a::int = 1;
如果您将类别存储在列中(虽然不是一个好的设计),您可以试试这个。
SELECT UniqueID , sum(CatX+CatY+CatZ+CatAA) over (partition by UniqueID) as "Sum across Categories",
CatX, CatY, CatZ, CatAA FROM (
SELECT 'Hairbdb' as UniqueID, 0 as CatX, 1 as CatY, 0 as CatZ, 1 as CatAA from dual
UNION ALL
SELECT 'Jshshsv', 0,0,0,1 from dual
);