根据group by按计数聚合SQL组

时间:2013-09-13 18:54:57

标签: sql group-by case

我有一个查询(这不是按预期工作)

SELECT 
(CASE 
    WHEN str LIKE '%some_string%' THEN 's'
    WHEN str LIKE '%some_string2%' THEN 's2'
END) as str,
COUNT(*) as num FROM Table WHERE
str LIKE '%some_string%' or
str LIKE '%some_string2%'
group by str

,表中包含

之类的内容
|      str                       |
|------------------------------- |
| "some_string_a;"               |  
| "some_string_b; some_else"     |  
| "some_string_c; some_else"     |  
| "some_else; some_string2a"     |  
| "some_string_c; some_string2b" |  

如何获得如下结果?

|      str      |   num  |
|---------------|--------|
| s             |   4    |
| s2            |   2    |

我目前正在计算不足,因为当1,2,3和5行实际包含两者时,它们被计为'some_string%'(因此是's')。

5 个答案:

答案 0 :(得分:1)

我更新的答案

<强> SQL Fiddle

试试这个

    CREATE table Table1 (str varchar(50));


    Insert into Table1(str) values('aaa');
    Insert into Table1(str) values('bbb');
    Insert into Table1(str) values('aaaaaaaaaa');
    Insert into Table1(str) values('bbbbbbbbbb');
    Insert into Table1(str) values('aaaaaaaaaaaaaaaa');
    Insert into Table1(str) values('aaabbbbb');
    Insert into Table1(str) values('ccccccccccccccc');


Select str , count(*) from
(
    SELECT 
    (CASE  
    WHEN str LIKE '%bbb%' THEN 's2'
    WHEN str LIKE '%aaa%' THEN 's'     
    END) as str
    FROM Table1 WHERE
    str LIKE '%aaa%' or
    str LIKE '%bbb%'
) as T group by str; -- will count in s2 means in a so s will be 3 and s2 is 3

答案 1 :(得分:0)

尝试切换CASE语句中的条件顺序。

SELECT 
(CASE 
    WHEN str LIKE '%some_string2%' THEN 's2'
    WHEN str LIKE '%some_string%' THEN 's'
END) as str,
COUNT(*) as num FROM Table WHERE
str LIKE '%some_string%' or
str LIKE '%some_string2%'
group by str

答案 2 :(得分:0)

你可以这样做。

SELECT SUM(IF(str LIKE '%some_string%',1,0)) AS s,
       SUM(IF(str LIKE '%some_string2%',1,0)) AS s2
FROM Table WHERE
str LIKE '%some_string%' or
str LIKE '%some_string2%'
group by str;

答案 3 :(得分:0)

您希望按select中的相同表达式进行分组:

SELECT (CASE WHEN str LIKE '%some_string%' THEN 's'
             WHEN str LIKE '%some_string2%' THEN 's2'
        END) as str,
       COUNT(*) as num
FROM Table
WHERE str LIKE '%some_string%' or
      str LIKE '%some_string2%'
group by (CASE WHEN str LIKE '%some_string%' THEN 's'
               WHEN str LIKE '%some_string2%' THEN 's2'
          END);

某些数据库允许在str中使用列别名(group by),但不是全部。使用完整表达式或使用子查询(由Dhaval建议)更安全。但是,我会把它写成:

select str, count(*)
from (select (CASE WHEN str LIKE '%some_string%' THEN 's'
                   WHEN str LIKE '%some_string2%' THEN 's2'
              END) as str
      from table
     ) t
where str is not null
group by str;

您不必重复比较,因为str在不匹配的情况下会获得NULL值。

答案 4 :(得分:0)

使用 Postgres n模式的一般解决方案可能如下所示:

SELECT p.pattern, count((str1 LIKE '%' || p.pattern || '%') OR NULL) AS  ct
FROM  (
   SELECT regexp_split_to_table(str, ';') AS str1
   FROM tbl
   ) x
CROSS  JOIN (
   VALUES ('some_string')
         ,('some_string2')
         -- more?
   ) AS p(pattern)
GROUP  BY p.pattern

结果:

pattern       | ct
--------------+----
some_string   | 6
some_string2  | 2

-> SQLfiddle demo

  • 假设您希望匹配字符串的每个部分,由;分隔。 Postgres函数regexp_split_to_table()以这种方式规范化您的数据。

  • 我还假设你想用任何模式计算每场比赛,而不是在第一场比赛后停止。

CASE语句只会产生一个匹配并抑制其余的匹配。所以我假设你想要那个。

相反,我交叉加入一个VALUES表达式,提供任意数量的模式。一般使用非常方便。您可以使用表或子查询来提供模式来代替VALUES表达式。