【问题标题】:Group by is throwing error in SQL ServerGroup by 在 SQL Server 中引发错误
【发布时间】:2017-05-18 15:47:36
【问题描述】:

我想按服务名称对我的所有记录进行分组,并且我在 SQL Server 中使用此查询,但它会引发错误

select max(c.service_id) as service_id, a.ser_id, b.UserID, 
    SQRT(POWER(69.1 * ( @latitude - b.Latitude),2) + POWER(69.1 * ( b.Longitude - @longitude ) * COS(b.Longitude / 57.3), 2)) as distance,
    c.service_name
from aspnet_bawe_services a 
left join aspnet_user_account b on a.bawe_id = b.UserID 
left join aspnet_services_app c on a.ser_id = c.service_id 
group by c.service_name

错误

消息 8120,级别 16,状态 1,过程 app_service_list,第 24 行
列“aspnet_bawe_services.ser_id”在选择列表中无效,因为它既不包含在聚合函数中,也不包含在 GROUP BY 子句中。

【问题讨论】:

  • 错误消息一目了然:您可以选择的唯一列是 service_name 或包含在聚合函数(如 MAX())中的其他列。而且由于您从未向我们展示示例输入和输出数据,因此只能猜测正确的查询。
  • 请提供一个可以回答的问题。根据您提供的查询,不可能弄清楚您想要什么,因为它主要由非法 SQL 组成。
  • 您有什么理由手动进行地理计算而不是使用对geography 的内置支持?
  • 简单规则:如果您使用GROUP BY,那么您的语句中的每一列必须要么GROUP BY 子句,OR 它必须由聚合函数处理,如 AVGCOUNTMINMAXSUM 等。 -- EVERY 其中之一 - 没有例外

标签: c# sql sql-server database


【解决方案1】:

你应该对不在聚合函数中的每一列进行分组,或者对这些列使用聚合函数

先这样

select  max(c.service_id) as service_id, a.ser_id ,b.UserID,SQRT(POWER(69.1 * ( @latitude - b.Latitude),2) + POWER(69.1 * ( b.Longitude - @longitude ) * COS(b.Longitude / 57.3), 2)) as distance,c.service_name
    from aspnet_bawe_services a 
    left join aspnet_user_account b on a.bawe_id=b.UserID 
    left join aspnet_services_app c on a.ser_id=c.service_id 
    group by c.service_name, a.ser_id,b.UserID,b.Latitude,b.Longitude

或者第二个这样的

    select  
    max(c.service_id) as service_id, 
    max(a.ser_id), max(b.UserID), 
    sum(SQRT(POWER(69.1 * ( @latitude - b.Latitude),2) + POWER(69.1 * ( b.Longitude - @longitude ) * COS(b.Longitude / 57.3), 2))) as distance,
    c.service_name
from 
    aspnet_bawe_services a 
left join 
    aspnet_user_account b on a.bawe_id = b.UserID 
left join 
    aspnet_services_app c on a.ser_id = c.service_id 
group by 
    c.service_name

【讨论】:

  • 我已经检查了您的查询,它抛出“消息 8120,级别 16,状态 1,过程 app_service_list,第 24 行列 'aspnet_user_account.Latitude' 在选择列表中无效,因为它不包含在任何一个聚合函数或 GROUP BY 子句。消息 8120,级别 16,状态 1,过程 app_service_list,第 24 行 列“aspnet_user_account.Longitude”在选择列表中无效,因为它既不包含在聚合函数或 GROUP BY 子句中. "
  • 你想要什么?分组纬度?或从纬度的最大值或最小值中选择?
  • 每一个 service_id 都可以有很多 Latitude,你正在对 service_id 进行分组,但不对 Latitude 做任何事情,你想选择最大值是多少?还是分组?
  • 我想按服务名称分组,我还需要基于我在查询中使用的纬度和经度的距离
【解决方案2】:

当您group by 时,这意味着您想要“压缩”多行,这些行对应于您想要分组的列中的一个值。因为所有列(除了您分组的列)都必须包含在聚合函数中(如maxsum 等),即使没有必要!因为SQL 不知道你可能知道什么:) 所以,你必须把a.ser_id 放在某个聚合中功能。

【讨论】:

  • 我也使用了这个查询“select max(c.service_id) as service_id, max(a.ser_id) as ser_id,max(b.UserID) as bawe_id,SQRT(POWER(69.1 * (@ latitude - b.Latitude),2) + POWER(69.1 * ( b.Longitude - @longitude ) * COS(b.Longitude / 57.3), 2)) as distance ,c.service_name from aspnet_bawe_services a left join aspnet_user_account b on a .bawe_id=b.UserID left join aspnet_services_app c on a.ser_id=c.service_id group by c.service_name"
【解决方案3】:

如果你想使用 group by,那么所有选择的列都应该在聚合函数中,如果你不想在这些列上应用任何聚合函数,那么它们必须在 group by 子句中。 在您的情况下,您应该尝试:

select  max(c.service_id) as service_id, a.ser_id ,b.UserID,SQRT(POWER(69.1 * ( @latitude - b.Latitude),2) + POWER(69.1 * ( b.Longitude - @longitude ) * COS(b.Longitude / 57.3), 2)) as distance,c.service_name
from aspnet_bawe_services a 
left join aspnet_user_account b on a.bawe_id=b.UserID 
left join aspnet_services_app c on a.ser_id=c.service_id 
group by c.service_name,**a.ser_id,b.UserID**

或者如果你不想要这个,你可以删除 a.ser_id,b.UserID

或者,如果您想要这些列,那么您必须在 a.ser_id、b.UserID 上应用 group by 或任何聚合函数,否则它们将无法工作,因为您的服务器看起来处于严格模式。因此,如果您想按原样运行查询,则必须在数据库上禁用严格模式。如果您使用的是 MYSQl,那么此链接可能会对您有所帮助 https://www.liquidweb.com/kb/how-to-disable-mysql-strict-mode/

【讨论】:

  • 不,我也想要那个。
  • 您必须在 a.ser_id,b.UserID 上应用 group by 或任何聚合函数,否则它们将无法工作,因为您的服务器看起来处于严格模式。因此,如果您想按原样运行查询,则必须在数据库上禁用严格模式。如果您使用的是 MYSQl,那么此链接可能会对您有所帮助 liquidweb.com/kb/how-to-disable-mysql-strict-mode
猜你喜欢
  • 2016-08-02
  • 1970-01-01
  • 1970-01-01
  • 2013-04-06
  • 1970-01-01
  • 1970-01-01
  • 2010-12-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多