围绕列表中的值的案例陈述

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;