基于分组依据聚合SQL分组依据计数
我有一个这样的问题(这不完全符合预期) 表中包含如下内容基于分组依据聚合SQL分组依据计数,sql,group-by,case,Sql,Group By,Case,我有一个这样的问题(这不完全符合预期) 表中包含如下内容 | str | |------------------------------- | | "some_string_a;" | | "some_string_b; some_else" | | "some_string_c; some_else" | | "some_else; some_string2a" | | "
| 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”)。请尝试在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
我的最新答案
试试这个
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
你可以这样做
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;
您想在
选择中按相同的表达式分组:
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
)在groupby
中使用,但不是全部。使用完整表达式或子查询(如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
值。对于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
- I假设您希望匹配字符串的每个部分,由
分隔代码>。Postgres函数regexp\u split\u to\u table()
以这种方式规范化数据
- 我还假设你想以任何模式统计每场比赛,而不是在第一场比赛后停止
一个CASE
语句只会产生一个匹配项,并抑制其余的匹配项。所以我想你不想这样
相反,我交叉连接到一个VALUES
表达式,该表达式提供您想要的任意多个模式。非常方便一般使用。您可以使用一个表或子查询来提供模式来代替值表达式。我不认为这可以处理“某个字符串在一行中的两个实例”的情况,但这是我最初的想法:pIt不会处理某个字符串在一行中的两个实例,您是对的。但它确实解决了当它应该转向s2时对单词s进行行计数的问题。为了处理您提出的问题,我可能会创建一个UDF,它返回模式在另一个字符串/行中出现的次数的整数。然后我们可以把它们相加。我不认为你可以在不变得非常复杂的情况下做到这一点——让值以列而不是行的形式返回是可以接受的吗?除非你绝对需要这样做,否则这可能是一个很好的结果。@rio你能检查我的答案吗?你必须首先规范化你的数据。@eouw0o83hf我认为下面是奥尔登的方法,对吗?@rio yep。如果这是一个可接受的响应,那么这将给您带来更轻松的时间;如果我插入aaabbb,它应该在其中计数,无论是在s中还是在s2中。。我认为,按照您的说法,它应该计入s2,所以在我的示例中,两个值都是3(在插入aaabbb之后)。。对??都应该是3,但是您的SQLFIDLE返回3和2(将第一行更改为aaabbbb)。我认为aaa应该被计算4次,不是吗?那么您的意思是s是4,s2是3???在这种情况下,Alden的ersponse是我认为这会创建额外的列的唯一方法,我想,但是我想我必须按s,s2排序,而且我事先不知道哪些列更像(所以可能是按s2排序,s更好)(当str像“%some_string%”时为大小写,当str像“%some_string 2%”时为's',然后为's2'结束);位。我需要按str分组,但按分组(当str像“%some_string%”时为大小写,当str像“%some_string 2%”时为's',然后为's2'结束)as str似乎玩得不太好。什么样的问题?你在使用什么数据库?这是标准的ANSI语法。这是一个优雅的解决方案,但不幸的是,数据实际上不那么干净,因此;假设实际上发生了故障。谢谢!我只能回答给出的问题。
pattern | ct
--------------+----
some_string | 6
some_string2 | 2