我有一个表格,如下所示,显示了类型的数量。我需要并且一直试图将数据显示为1列和7行而不是......但没有成功。
__________________________________________________________________________ | col types | win2k | winxp | win2k3 | vista | win7 | win8 | win8.1 | -------------------------------------------------------------------------- | count of types | 2365 | 65655 | 422445 | 4822 | 482 | 2331 | 485323 | --------------------------------------------------------------------------
Select
count(case when col1 ~* '5.0.2195' then 1 else null end) as Win2k,
count(case when col1 ~* '5.1.2600' then 1 else null end) as WinXP,
count(case when col1 ~* '5.2.3790' then 1 else null end) as W2k3,
count(case when (col1 ~* '6.0.6000'
or col1 ~* '6.0.6001' or col1 ~* '6.0.6002')
then 1 else null end) as Vista,
count(case when (col1 ~* '6.1.7600'
or col1 ~* '6.1.7601')
then 1 else null end) as Win7,
count(case when col1 ~* '6.2.9200' then 1 else null end) as Win8,
count(case when (col1 ~* '6.3.9200'
or col1 ~* '6.3.9600')
then 1 else null end) as "Win8.1"
From col1
理想情况下,它看起来像这样:
___________________ | types | count | ------------------- | win2k | 2365 | | winxp | 65655 | | win2k3 | 422445 | | vista | 4822 | | win7 | 482 | | win8 | 2331 | | win8.1 | 485323 | -------------------
注意:
答案 0 :(得分:0)
我喜欢使用Postgres特定的并行unnest()
:
SELECT unnest('{win2k,winxp,win2k3,vista,win7,win8,win8.1}'::text[]) AS type
,unnest(ARRAY[
count(some_column ~ '5.0.2195' OR NULL)
,count(some_column ~ '5.1.2600' OR NULL)
.. the rest from your query above ...
]) AS ct
FROM profile.foo
两个数组中的值和序列号必须匹配 相关答案以及更多细节(请务必阅读!):
count()
仅计算非空值..
(TRUE OR NULL) IS TRUE
(FALSE OR NULL) IS NULL
(NULL OR NULL) IS NULL
VOILÀ。仅计算TRUE
。 More details in this answer on dba.SE.
除此之外:在表达式中使用~
instead of ~*
,因为这些字符串文字中没有区分大小写的字母。但我怀疑你需要一个正则表达式匹配。
此外,列名profile.foo
没有意义,因为唯一的表名为foo
,而不是profile
答案 1 :(得分:0)
这些类型的查询更容易以GROUP BY为目标,如下所示:
Select
case when profile.foo ~* '5.0.2195' then 'Win2k'
when profile.foo ~* '5.1.2600' then 'WinXP'
when profile.foo ~* '5.2.3790' then 'W2k3'
when (profile.foo ~* '6.0.6000'
or profile.foo ~* '6.0.6001'
or profile.foo ~* '6.0.6002')
then 'Vista'
when (profile.foo ~* '6.1.7600'
or profile.foo ~* '6.1.7601')
then 'Win7'
when profile.foo ~* '6.2.9200' then 'Win8'
when (profile.foo ~* '6.3.9200'
or profile.foo ~* '6.3.9600')
then 'Win8.1' ELSE 'Other' END as type,
count(*) as cnt
From profile
GROUP BY 1
如下所述,此查询适用于互斥的情况,即当profile.foo
包含表示每行一个操作系统的值时
答案 2 :(得分:0)
不要使用条件聚合,只需使用CASE
正确填充Type
,然后在Type
上分组:
;with cte AS (Select case when profile.foo ~* '5.0.2195' then 'Win2k'
when profile.foo ~* '5.1.2600' then 'WinXP'
when profile.foo ~* '5.2.3790' then 'W2k3'
when profile.foo ~* '6.0.6000' or profile.foo ~* '6.0.6001' or profile.foo ~* '6.0.6002' then 'Vista'
when (profile.foo ~* '6.1.7600' or profile.foo ~* '6.1.7601') then 'Win7'
when profile.foo ~* '6.2.9200' then 'Win8'
when (profile.foo ~* '6.3.9200' or profile.foo ~* '6.3.9600') then 'Win8.1'
end as Type
From profile.foo)
SELECT Type,COUNT(*) AS ct
FROM cte
GROUP BY Type
对于postgresql语法不是100%,但逻辑是兼容的。