-2

我有一个如下所示的表格,其中显示了类型的数量。我需要并且一直在尝试将数据显示为 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 |
-------------------

笔记:

  • 我正在使用带有 PGADMIN III 的 Postgresql 9.3
  • 我无法创建任何自定义函数
  • 是否有更多的列来完成这项工作并不重要
4

3 回答 3

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

瞧。只TRUE计算。有关 dba.SE 的此答案的更多详细信息。

旁白:在表达式中使用~而不是~*,因为这些字符串文字中没有区分大小写的字母。但我怀疑你是否需要正则表达式匹配。

此外,列名profile.foo没有意义,因为唯一的表是 named foo,而不是profile

于 2014-09-11T22:31:15.657 回答
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包含表示每行一个操作系统的值时

于 2014-09-11T22:32:58.577 回答
0

而不是使用条件聚合,只需用于CASE填充Type适当的 then 组 on 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

不是 100% 使用 postgresql 语法,但逻辑是兼容的。

于 2014-09-11T22:34:17.947 回答