如何使用 case when 和 partition by in SQL 将多个值合并为一个值?
How to consolidate multiple values into one value using case when and partition by in SQL?
我有一个 table,其中在一个字段中包含 3 个不同的名称、这些名称关联的相应帐户、唯一 ID、每对的总计数以及基于总计数的排名列价值。此处示例:
LOGO | Account | ID | Count_Per_Logo | Rank
Walmart Acct_A ABC 3 1
Walmart Acct_A DEF 3 1
Walmart Acct_A GHI 3 1
Vudu Acct_A JKL 1 2
Bonobos Acct_A MNO 1 2
我的目标是 'consolidate' LOGO 字段变成一个帐户的一个徽标 - 因此对于每个唯一 ID - 它们应该只与 1 个徽标相关联(而不是上面显示的 3 个)。
期望的输出
LOGO | Account | ID | Count_Per_Logo | Rank | Consolidated_LOGO
Walmart Acct_A ABC 3 1 Walmart
Walmart Acct_A DEF 3 1 Walmart
Walmart Acct_A GHI 3 1 Walmart
Vudu Acct_A JKL 1 2 Walmart
Bonobos Acct_A MNO 1 2 Walmart
现在我正在使用带有分区依据的计数来获得排名 - 但我不确定如何根据排名值创建一个具有 'desired logo' 的新字段 - 滞后函数是这有必要吗?任何帮助将不胜感激
当前逻辑
SELECT LOGO, ACCOUNT, ID FROM
(SELECT *, DENSE_RANK() OVER (PARTITION BY ACCOUNT ORDER BY LOGO_NAME_CNT DESC) AS LOGO_RANK
FROM
(SELECT *, count(ACCOUNT) over (partition by LOGO) AS LOGO_NAME_CNT FROM "TABLE1" WHERE ACCOUNT = 'Acct_A')
)
WHERE LOGO_RANK = 1
看来你的基础 SQL 是:
SELECT
a.*
,dense_rank() over (partition by account order by count_per_logo desc) as rank
FROM (
SELECT
logo
,account
,id
,count(logo) over (partition by account, logo) as count_per_logo
FROM VALUES
('walmart', 'acct_a', 'abc'),
('walmart', 'acct_a', 'def'),
('walmart', 'acct_a', 'ghi'),
('vudu', 'acct_a', 'jkl'),
('bonobos', 'acct_a', 'mno')
v(logo, account, id)
) AS a
ORDER BY 4 DESC, 5;
那么您只需添加一个 FIRST_VALUE,例如:
SELECT
a.*
,dense_rank() over (partition by account order by count_per_logo desc) as rank
,first_value(logo) over (partition by account order by count_per_logo desc) as Consolidated_LOGO
FROM (
SELECT
logo
,account
,id
,count(logo) over (partition by account, logo) as count_per_logo
FROM VALUES
('walmart', 'acct_a', 'abc'),
('walmart', 'acct_a', 'def'),
('walmart', 'acct_a', 'ghi'),
('vudu', 'acct_a', 'jkl'),
('bonobos', 'acct_a', 'mno')
v(logo, account, id)
) AS a
ORDER BY 4 DESC, 5;
这给出::
LOGO
ACCOUNT
ID
COUNT_PER_LOGO
RANK
CONSOLIDATED_LOGO
walmart
acct_a
abc
3
1
walmart
walmart
acct_a
def
3
1
walmart
walmart
acct_a
ghi
3
1
walmart
vudu
acct_a
jkl
1
2
walmart
bonobos
acct_a
mno
1
2
walmart
只要您没有关系,Simeon 的回答就应该有效。其实,如果你不在乎领带,那就更简单了
select logo,
account,
id,
mode(logo) over (partition by account) as consolidated_logo
from your_table;
如果您希望为与计数有关的每个徽标实例复制结果集,请考虑以下内容
with cte as
(select logo, account
from your_table
group by logo, account
qualify max(count(*)) over (partition by account)=count(*))
select a.*, b.logo as consolidated_logo
from your_table a
join cte b on a.account=b.account
order by b.logo;
我有一个 table,其中在一个字段中包含 3 个不同的名称、这些名称关联的相应帐户、唯一 ID、每对的总计数以及基于总计数的排名列价值。此处示例:
LOGO | Account | ID | Count_Per_Logo | Rank
Walmart Acct_A ABC 3 1
Walmart Acct_A DEF 3 1
Walmart Acct_A GHI 3 1
Vudu Acct_A JKL 1 2
Bonobos Acct_A MNO 1 2
我的目标是 'consolidate' LOGO 字段变成一个帐户的一个徽标 - 因此对于每个唯一 ID - 它们应该只与 1 个徽标相关联(而不是上面显示的 3 个)。
期望的输出
LOGO | Account | ID | Count_Per_Logo | Rank | Consolidated_LOGO
Walmart Acct_A ABC 3 1 Walmart
Walmart Acct_A DEF 3 1 Walmart
Walmart Acct_A GHI 3 1 Walmart
Vudu Acct_A JKL 1 2 Walmart
Bonobos Acct_A MNO 1 2 Walmart
现在我正在使用带有分区依据的计数来获得排名 - 但我不确定如何根据排名值创建一个具有 'desired logo' 的新字段 - 滞后函数是这有必要吗?任何帮助将不胜感激
当前逻辑
SELECT LOGO, ACCOUNT, ID FROM
(SELECT *, DENSE_RANK() OVER (PARTITION BY ACCOUNT ORDER BY LOGO_NAME_CNT DESC) AS LOGO_RANK
FROM
(SELECT *, count(ACCOUNT) over (partition by LOGO) AS LOGO_NAME_CNT FROM "TABLE1" WHERE ACCOUNT = 'Acct_A')
)
WHERE LOGO_RANK = 1
看来你的基础 SQL 是:
SELECT
a.*
,dense_rank() over (partition by account order by count_per_logo desc) as rank
FROM (
SELECT
logo
,account
,id
,count(logo) over (partition by account, logo) as count_per_logo
FROM VALUES
('walmart', 'acct_a', 'abc'),
('walmart', 'acct_a', 'def'),
('walmart', 'acct_a', 'ghi'),
('vudu', 'acct_a', 'jkl'),
('bonobos', 'acct_a', 'mno')
v(logo, account, id)
) AS a
ORDER BY 4 DESC, 5;
那么您只需添加一个 FIRST_VALUE,例如:
SELECT
a.*
,dense_rank() over (partition by account order by count_per_logo desc) as rank
,first_value(logo) over (partition by account order by count_per_logo desc) as Consolidated_LOGO
FROM (
SELECT
logo
,account
,id
,count(logo) over (partition by account, logo) as count_per_logo
FROM VALUES
('walmart', 'acct_a', 'abc'),
('walmart', 'acct_a', 'def'),
('walmart', 'acct_a', 'ghi'),
('vudu', 'acct_a', 'jkl'),
('bonobos', 'acct_a', 'mno')
v(logo, account, id)
) AS a
ORDER BY 4 DESC, 5;
这给出::
LOGO | ACCOUNT | ID | COUNT_PER_LOGO | RANK | CONSOLIDATED_LOGO |
---|---|---|---|---|---|
walmart | acct_a | abc | 3 | 1 | walmart |
walmart | acct_a | def | 3 | 1 | walmart |
walmart | acct_a | ghi | 3 | 1 | walmart |
vudu | acct_a | jkl | 1 | 2 | walmart |
bonobos | acct_a | mno | 1 | 2 | walmart |
只要您没有关系,Simeon 的回答就应该有效。其实,如果你不在乎领带,那就更简单了
select logo,
account,
id,
mode(logo) over (partition by account) as consolidated_logo
from your_table;
如果您希望为与计数有关的每个徽标实例复制结果集,请考虑以下内容
with cte as
(select logo, account
from your_table
group by logo, account
qualify max(count(*)) over (partition by account)=count(*))
select a.*, b.logo as consolidated_logo
from your_table a
join cte b on a.account=b.account
order by b.logo;