围绕列表中的值的案例陈述
Case statements around values in a list
我有一个 table 在执行某些连接后如下所示:
create table test(id varchar(10), sub varchar(20));
insert into test values(1,'a')
insert into test values(1,'b')
insert into test values(2,'a')
insert into test values(3,'a')
insert into test values(3,'c')
我想查看特定 id 在子列中的值,并输出如下(预期结果):
1,'both a and b'
2,'only a'
3,'both a and c'
我尝试了以下方法:
select id, case when sub in ('a') then 'only a'
when sub in ('a','b') then 'both a and b')
else 'only b'
end as subs from test group by 1,2;
如有任何帮助,我们将不胜感激。
对于 sql 服务器:
您可以使用,它会按 id
列出它拥有的子项
select distinct id ,
STUFF((Select ','+sub
from #test T1
where T1.id=T2.id
FOR XML PATH('')),1,1,'') from #test T2
where id = 3
对于 postgres,使用
SELECT
id,
ARRAY_AGG (sub) as sugagg
from #test T1
GROUP BY
id
您可以进行自连接:
SELECT
ta.id,
CASE WHEN ta.id is NULL THEN
CASE WHEN tb.id IS NULL then 'neither' ELSE '"b" only'
ELSE
CASE WHEN tb.id IS NULL then '"a" only' ELSE '"a" and "b"'
END AS summary
FROM test ta
FULL OUTER JOIN test tb
ON ta.id = tb.id AND tb.sub = 'b'
WHERE ta.sub='a'
如果你可以使用 sql 服务器试试这个解决方案
SELECT
SS.id,
STUFF((SELECT 'and' + SS.sub
FROM test ts
WHERE ts.id = SS.id
FOR XML PATH('')), 1, 1, '') [sub]
FROM test SS
GROUP BY SS.id
ORDER BY 1
您可以进行聚合:
select id, (case when max(sub) = min(sub) and min(sub) = 'a'
then 'only a'
when max(sub) = min(sub) and min(sub) = 'b'
then 'only b'
when max(sub) <> min(sub)
then 'both a and b'
end)
from test t
where t.sub in ('a', 'b')
group by id;
编辑: 删除了 where
子句并进行连接。
select id, (case when max(sub) = min(sub)
then 'only' || min(sub)
when max(sub) <> min(sub)
then 'multiple'
end)
from test t
group by id;
奇怪的结果。我宁愿有完整的清单。但无论如何:
select id,
(case when max(sub) = min(sub)
then 'only ' || min(sub)
when count(distinct sub) = 2
then 'both ' || min(sub) || ' and ' || max(sub)
else 'I don''t have that many fingers.
end)
from test t
group by id;
如果您想要完整列表,请使用 listagg()
:
select id, listagg(distinct sub, ',') within group (order by sub)
from test t
group by id;
我有一个 table 在执行某些连接后如下所示:
create table test(id varchar(10), sub varchar(20));
insert into test values(1,'a')
insert into test values(1,'b')
insert into test values(2,'a')
insert into test values(3,'a')
insert into test values(3,'c')
我想查看特定 id 在子列中的值,并输出如下(预期结果):
1,'both a and b'
2,'only a'
3,'both a and c'
我尝试了以下方法:
select id, case when sub in ('a') then 'only a'
when sub in ('a','b') then 'both a and b')
else 'only b'
end as subs from test group by 1,2;
如有任何帮助,我们将不胜感激。
对于 sql 服务器:
您可以使用,它会按 id
列出它拥有的子项select distinct id ,
STUFF((Select ','+sub
from #test T1
where T1.id=T2.id
FOR XML PATH('')),1,1,'') from #test T2
where id = 3
对于 postgres,使用
SELECT
id,
ARRAY_AGG (sub) as sugagg
from #test T1
GROUP BY
id
您可以进行自连接:
SELECT
ta.id,
CASE WHEN ta.id is NULL THEN
CASE WHEN tb.id IS NULL then 'neither' ELSE '"b" only'
ELSE
CASE WHEN tb.id IS NULL then '"a" only' ELSE '"a" and "b"'
END AS summary
FROM test ta
FULL OUTER JOIN test tb
ON ta.id = tb.id AND tb.sub = 'b'
WHERE ta.sub='a'
如果你可以使用 sql 服务器试试这个解决方案
SELECT
SS.id,
STUFF((SELECT 'and' + SS.sub
FROM test ts
WHERE ts.id = SS.id
FOR XML PATH('')), 1, 1, '') [sub]
FROM test SS
GROUP BY SS.id
ORDER BY 1
您可以进行聚合:
select id, (case when max(sub) = min(sub) and min(sub) = 'a'
then 'only a'
when max(sub) = min(sub) and min(sub) = 'b'
then 'only b'
when max(sub) <> min(sub)
then 'both a and b'
end)
from test t
where t.sub in ('a', 'b')
group by id;
编辑: 删除了 where
子句并进行连接。
select id, (case when max(sub) = min(sub)
then 'only' || min(sub)
when max(sub) <> min(sub)
then 'multiple'
end)
from test t
group by id;
奇怪的结果。我宁愿有完整的清单。但无论如何:
select id,
(case when max(sub) = min(sub)
then 'only ' || min(sub)
when count(distinct sub) = 2
then 'both ' || min(sub) || ' and ' || max(sub)
else 'I don''t have that many fingers.
end)
from test t
group by id;
如果您想要完整列表,请使用 listagg()
:
select id, listagg(distinct sub, ',') within group (order by sub)
from test t
group by id;