我有一个如下表
name
-----------
1@apple@1
2@apple@2
3@apple@4
4@box@4
5@box@5
我想得到的结果是:
name
--------------
apple 3
box 2
预先感谢您的帮助
答案 0 :(得分:2)
这就是您所需要的。
select
SUBSTRING(
name,
CHARINDEX('@', name) + 1,
LEN(name) - (
CHARINDEX('@', REVERSE(name)) + CHARINDEX('@', name)
)
),
count(1)
from
tbl
group by
SUBSTRING(
name,
CHARINDEX('@', name) + 1,
LEN(name) - (
CHARINDEX('@', REVERSE(name)) + CHARINDEX('@', name)
)
)
答案 1 :(得分:1)
用例何时
select case when name like '%apple%' then 'apple'
when name like '%box%' then 'box' end item_name,
count(*)
group by cas when name like '%apple%' then 'apple'
when name like '%box%' then 'box' end
答案 2 :(得分:1)
如果您的数据不包含任何句号(或句点,具体取决于您的本地语言),并且字符串的长度小于128个字符,则可以使用PARSENAME
有效地将您的字符串分成多个部分,然后提取第二部分:
DECLARE @T TABLE (Val VARCHAR(20));
INSERT @T (Val)
VALUES ('1@apple@1'), ('2@apple@2'), ('3@apple@4'),
('4@box@4'), ('5@box@5');
SELECT Val = PARSENAME(REPLACE(t.Val, '@', '.'), 2),
[Count] = COUNT(*)
FROM @T AS t
GROUP BY PARSENAME(REPLACE(t.Val, '@', '.'), 2);
否则,您将需要使用CHARINDEX
来查找字符串中@
的第一个和最后一个匹配项(也需要REVERSE
才能获得最后一个位置),然后使用{{ 3}}提取这些位置之间的文本:
DECLARE @T TABLE (Val VARCHAR(20));
INSERT @T (Val)
VALUES ('1@apple@1'), ('2@apple@2'), ('3@apple@4'),
('4@box@4'), ('5@box@5');
SELECT Val = SUBSTRING(t.Val, x.FirstPosition + 1, x.LastPosition - x.FirstPosition),
[Count] = COUNT(*)
FROM @T AS t
CROSS APPLY
( SELECT CHARINDEX('@', t.Val) ,
LEN(t.Val) - CHARINDEX('@', REVERSE(t.Val))
) AS x (FirstPosition, LastPosition)
GROUP BY SUBSTRING(t.Val, x.FirstPosition + 1, x.LastPosition - x.FirstPosition);
答案 3 :(得分:1)
未指定DBMS,因此这里是postgres
的变体。该查询确实使用regexp
来简化操作。
with t0 as (
select '1@apple@1' as value
union all select '2@apple@2'
union all select '3@apple@4'
union all select '4@box@4'
union all select '5@box@5'
),
trimmed as (
select regexp_replace(value,'[0-9]*@(.+?)@[0-9]*','\1') as name
from t0
)
select name, count(*)
from trimmed
group by name
order by name
更新
对于Oracle DMBS,查询基本上保持不变:
with t0 as ( select '1@apple@1' as value from dual union all select '2@apple@2' from dual union all select '3@apple@4' from dual union all select '4@box@4' from dual union all select '5@box@5' from dual ), trimmed as ( select regexp_replace(value,'[0-9]*@(.+?)@[0-9]*','\1') as name from t0 ) select name, count(*) from trimmed group by name order by name
NAME | COUNT(*) :---- | -------: apple | 3 box | 2
db <>提琴here
更新
MySQL 8.0
with t0 as ( select '1@apple@1' as value union all select '2@apple@2' union all select '3@apple@4' union all select '4@box@4' union all select '5@box@5' ), trimmed as ( select regexp_replace(value,'[0-9]*@(.+?)@[0-9]*','$1') as name from t0 ) select name, count(*) from trimmed group by name order by name
name | count(*) :---- | -------: apple | 3 box | 2
db <>提琴here
答案 4 :(得分:0)
您可以使用case
和group by
进行相同的操作。
select new_col , count(new_col)
from
(
select case when col_name like '%apple%' then 'apple'
when col_name like '%box%' then 'box'
else 'others' end new_col
from table_name
)
group by new_col
;