3

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

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

我想做一个 SQL 查询来计算每个“名称”出现在表上的次数。但是,我需要其中一些值来计算它们是否相同。例如,一个普通的 group by 查询将是:

  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

4 回答 4

3

You can make translation with case. Also, you can use subquery or CTE so you don't have 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

or with with online translation table:

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)
于 2013-09-06T16:52:57.340 回答
2

If you need A and B, D and E, to count the same, you can build a query like this:

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.

于 2013-09-06T16:52:41.073 回答
0

With a layer of abstraction and a CASE (SQL 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

With a translation table (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, you can also do this with a VALUES derived table instead of a real table (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)
于 2013-09-06T16:53:28.047 回答
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;
于 2013-09-06T17:04:17.917 回答