子查询仅返回所有行的第一行

时间:2019-09-12 07:38:08

标签: sql sql-server subquery

我有一个名为customer的表,由该客户居住的城市列组成,service_code是该客户支付的服务。我想显示客户居住的城市,每个城市的客户数量以及该城市最喜欢的服务。

目标

我想向城市展示,城市中有多少客户,这是城市中最受欢迎的服务。

客户表

id |  city  | service
1  |honkong | a
2  |la      | a
3  |la      | b
4  |hongkong| b
5  |taiwan  | a
6  |bangkok | b
7  |bangkok | d
...

我尝试过的代码

   SELECT w_city
  ,count(w_city) as all
  , (select TOP 1 service_code from customer
        group by service_code
        order by count (service_code) desc) 
        AS favorit
 FROM customer
  group by w_city 

问题

w_city列和所有列都工作正常,但问题来自于favourit列,该列仅显示第一个权利。其余所有与收藏夹列的第一行相同。

| w_city | all |favorit|
|hongkong| 100 | a
|la      | 40  | a
|taiwan  | 22  | a
|bangkok | 23  | a

结果应该是

| w_city | all |favorit|
|hongkong| 100 | a
|la      | 40  | b
|taiwan  | 22  | b
|bangkok | 23  | d

我的代码有什么问题?

2 个答案:

答案 0 :(得分:1)

似乎您需要一个相关的子查询:

SELECT w_city,
       COUNT(w_city) as all,
       (SELECT TOP 1 service_code
          FROM customer
         WHERE w_city = c.w_city
         GROUP BY service_code
         ORDER BY count(service_code) DESC ) AS favorit
  FROM customer c
 GROUP BY by w_city 

答案 1 :(得分:1)

您尝试按降序加入服务代码,因此需要通过select STRING_AGG(Tool.ID,',') As ToolId, STRING_AGG(Tool.Name,',') As ToolName, TGroup.Id AS GroupId, TGroup.Name AS GroupName, Base.Id, Base.Position, Task.Definition, Task.IsEvaluationActive FROM dbo.CustomTask AS Task INNER JOIN dbo.TaskBase AS Base ON Task.Id = Base.Id LEFT OUTER JOIN dbo.TaskGroup AS TGroup ON Base.TaskGroupId = TGroup.Id LEFT OUTER JOIN dbo.ToolTaskGroupMapping AS Map ON TGroup.Id = Map.TaskGroupId LEFT OUTER JOIN dbo.Tool AS Tool ON Map.ToolId = Tool.Id) t1 GROUP BY t1.GroupId, t1.GroupName, t1.Id, t1.Position, t1.Definition, t1.IsEvaluationActive

加入
select 
    dbo.GROUP_CONCAT(Tool.ID) As ToolId, 
    dbo.GROUP_CONCAT(Tool.Name) As ToolName,
    TGroup.Id AS GroupId, TGroup.Name AS GroupName, Base.Id,
    Base.Position, Task.Definition, Task.IsEvaluationActive
FROM dbo.CustomTask AS Task INNER JOIN
    dbo.TaskBase AS Base ON Task.Id = Base.Id LEFT OUTER JOIN
    dbo.TaskGroup AS TGroup ON Base.TaskGroupId = TGroup.Id LEFT OUTER JOIN
    dbo.ToolTaskGroupMapping AS Map ON TGroup.Id = Map.TaskGroupId LEFT OUTER JOIN
    dbo.Tool AS Tool ON Map.ToolId = Tool.Id) t1
GROUP BY t1.GroupId, t1.GroupName, t1.Id, t1.Position, t1.Definition, t1.IsEvaluationActive