SQL Query with group by子句,但计算两个不同的值,就好像它们是相同的一样

时间:2013-09-06 16:49:26

标签: sql sql-server sql-server-2008-r2

我有一个包含两列的简单表格,如下所示:

Id | Name
 0 |   A
 1 |   A
 2 |   B
 3 |   B
 4 |   C
 5 |   D
 6 |   E
 7 |   E

我想创建一个SQL查询,它将计算每个“名称”出现在表上的次数。但是,我需要将这些值中的一些数量视为相同。例如,查询的正常组将是:

  select Name, count(*)
    from table
group by Name

上述查询会产生结果:

Name | Count
  A  |   2
  B  |   2
  C  |   1
  D  |   1
  E  |   2

但我需要查询将“A”和“B”计算为只是“A”,并将“D”和“E”计算为好像它们只是“D”,这样结果就会如:

Name | Count
  A  |   4            // (2 "A"s + 2 "B"s)
  C  |   1
  D  |   3            // (1 "D"  + 2 "E"s)

如何进行此类查询?

4 个答案:

答案 0 :(得分:3)

您可以使用case进行翻译。此外,您可以使用子查询或CTE,因此您没有to repeat yourself

with cte as (
    select
        case Name
            when 'B' then 'A'
            when 'E' then 'D'
            else Name
        end as Name
    from table
)
select Name, count(*)
from cte
group by Name

或与在线翻译表一起使用:

select
    isnull(R.B, t.Name), count(*)
from table as t
    left outer join (
        select 'A', 'B' union all
        select 'E', 'D'
    ) as R(A, B) on R.A = t.Name
group by isnull(R.B, t.Name)

答案 1 :(得分:2)

如果您需要ABDE,要计算相同数量,您可以构建如下查询:

SELECT
    CASE Name WHEN 'B' THEN 'A' WHEN 'E' THEN 'D' ELSE Name END as Name
,   COUNT(*)
FROM table
GROUP BY CASE Name WHEN 'B' THEN 'A' WHEN 'E' THEN 'D' ELSE Name END

Demo on sqlfiddle

答案 2 :(得分:0)

使用抽象层和CASESQL Fiddle example):

;WITH x AS
(
    SELECT CASE Name WHEN 'B' THEN 'A'
                     WHEN 'E' THEN 'D'
                     ELSE Name
           END AS Name
    FROM Table1
)
SELECT Name, COUNT(1)
FROM x
GROUP BY Name

使用转换表(SQL Fiddle):

CREATE TABLE Translate(FromName char(1), ToName char(1));

INSERT INTO Translate VALUES ('B', 'A'), ('E', 'D');

SELECT COALESCE(t.ToName, a.Name) Name, COUNT(1)
FROM Table1 a
LEFT OUTER JOIN Translate t ON a.Name = t.FromName
GROUP BY COALESCE(t.ToName, a.Name)

FWIW,您也可以使用VALUES派生表而不是真实表(SQL Fiddle)来执行此操作:

SELECT COALESCE(t.ToName, a.Name) Name, COUNT(1)
FROM Table1 a
LEFT OUTER JOIN 
(
    VALUES ('B', 'A'), 
           ('E', 'D')
) t(FromName, ToName) ON a.Name = t.FromName
GROUP BY COALESCE(t.ToName, a.Name)

答案 3 :(得分:0)

这是有效的

 select t.a,count(t.id) from  (
       select case name when 'A' then 'A' when 'B' then 'A' 
                        when 'C' then 'C' when 'D' then 'C'
                        when 'D' then 'D' when 'E' then 'D' end as A,id
        from test) as t
    group by A;