使用GROUP BY子句用单个值替换不同的行

时间:2013-07-11 07:53:58

标签: sql sql-server tsql

我正在尝试做一些事情(当然是假的):

SELECT 
  city,
  CASE WHEN COUNT( [group] ) > 1 THEN 'Multiple' ELSE [group] END  AS Type 
FROM 
  offices
GROUP BY
  city

办公室包含以下行:

ID |   group   |  city
----------------------
1  |    'A'    | 'Houston'
2  |    'B'    | 'Houston'
3  |    'C'    | 'Houston'
4  |    'S'    | 'Boston'
5  |    'R'    | 'Detroit'

结果看起来像是:

   city   | group
--------------------
 'Houston'| 'Multiple'
 'Boston' |   'S'
 'Detroit'|   'R'

我知道你可以这样做:

SELECT 
  City,
  CASE WHEN COUNT([group]) > 1 THEN 
      'Multiple'
  ELSE 
       ( SELECT [group] FROM test WHERE t.City = city )
  END AS CGroup

FROM 
   test t
GROUP BY 
   City

我认为这应该更简单 没有子查询的东西?

3 个答案:

答案 0 :(得分:8)

您可以找到该列的MINMAX,然后在它们不相同时执行操作:

declare @t table (ID int not null,[group] char(1) not null,city varchar(20) not null)
insert into @t(ID,[group],city) values
(1,'A','Houston'),
(2,'B','Houston'),
(3,'C','Houston'),
(4,'S','Boston' ),
(5,'R','Detroit')

select city,
   CASE
      WHEN MIN([group]) != MAX([group]) THEN 'Multiple'
      ELSE MAX([group]) END as [group]
from @t
group by city

尽管服务器在MAX子句中出现两次,但服务器应足够智能,只能实际运行select聚合一次。

结果:

city                 group
-------------------- --------
Boston               S
Detroit              R
Houston              Multiple

答案 1 :(得分:2)

@Damien_The_Unbeliever's answer很完美。这个是另一种选择。如果您想检查多个(例如COUNT(GROUP) > 2)。只需在MIN中使用MAXELSE,就像这样:

SELECT 
  city,
  CASE WHEN COUNT([group]) > 2 
       THEN 'Multiple' 
       ELSE MAX([group]) END  AS Type 
FROM 
  offices
GROUP BY
  city

请参阅this SQLFiddle

答案 2 :(得分:0)

使用您的第一个查询,但只需使用MIN部分中的ELSE

SELECT 
    City, 
    CASE
        WHEN COUNT(*) > 1 THEN 'Multiple'
        ELSE MIN(CityGroup)
    END AS CityGroup
FROM Test
GROUP BY CityGroup