【问题标题】:How to use SQL Case in Group by Clause?如何在 Group by Clause 中使用 SQL Case?
【发布时间】:2016-10-30 15:59:19
【问题描述】:

我在我的 select 和 group by 子句中使用 SQL Case,我正在使用 JAVA。每当我执行我的 java 程序时,它都会说:

列 'dbo.JOHN_Dashboard.Log_Date' 在选择列表中无效,因为它既不包含在聚合函数中,也不包含在 GROUP BY 子句中。

我的查询是:

SELECT EP.Site_Code AS [Site_Code], DB.[Site] AS [Site], DB.[Utility] AS [Utility], 
        CASE ? WHEN 'Raw' THEN dateadd(mi,datediff(mi,0,DB.[log_date]),0) 
        WHEN 'Hour'  THEN dateadd(hh,datediff(hh,0,DB.[log_date]),0)
        WHEN 'Day'   THEN dateadd(dd,datediff(dd,0,DB.[log_date]),0)
        WHEN 'Week'  THEN dateadd(wk,datediff(wk,0,DB.[log_date]),0)
        WHEN 'Month' THEN dateadd(mm,datediff(mm,0,DB.[log_date]),0)
        WHEN 'Year'  THEN dateadd(yy,datediff(yy,0,DB.[log_date]),0)                                                     
        ELSE DB.[log_date]
        END AS [log_date],
        SUM(CASE WHEN DB.[value] >= 0 THEN DB.[value] ELSE 0 END) AS [value],
        SUM(CASE WHEN DB.[Cost] >=0 THEN DB.[cost] ELSE 0 END) AS [Cost],
        SUM(CASE WHEN DB.[CO2] >=0 THEN DB.[CO2] ELSE 0 END) AS [CO],
        MT.[Meter_type_name] AS [Meter Type],
        MN.[Meter_Name] AS [Meter Name],
        U.[Unit_Name] AS [Units],
        EP.EnergyPoint_ID AS [Meter_ID],
        EP.Parent_ID AS [Parent],
        EP.Meter_Description AS [Meter_Description] 
FROM [dbo].[JOHN_Dashboard] DB
INNER JOIN [dbo].[EnergyPoints] EP ON DB.[EnergyPoint_ID] = EP.[EnergyPoint_ID] 
INNER JOIN [dbo].[Meter_Types] MT ON MT.[Meter_Type_ID] = EP.[Meter_Type_ID]
INNER JOIN [dbo].[Meter_Names] MN ON MN.[Meter_Name_ID] = EP.[Meter_Name_ID]
INNER JOIN [dbo].[Units] U ON U.[Unit_ID] = EP.[Unit_id]
WHERE [log_date] >= ? AND [Log_Date] < DATEADD(DAY, 1, ?)
AND ( ? IS NULL OR EP.Energypoint_ID = ?)
GROUP BY EP.Site_Code, DB.[Site], DB.[Utility], MT.[Meter_type_name],           
        MN.[Meter_Name], U.[Unit_Name], EP.[EnergyPoint_ID],
        EP.[Parent_ID], EP.[Meter_Description],
        CASE ? WHEN 'Raw' THEN dateadd(mi,datediff(mi,0,DB.[log_date]),0)
        WHEN 'Hour'  THEN dateadd(hh,datediff(hh,0,DB.[log_date]),0)
        WHEN 'Day'   THEN dateadd(dd,datediff(dd,0,DB.[log_date]),0)
        WHEN 'Week'  THEN dateadd(wk,datediff(wk,0,DB.[log_date]),0)
        WHEN 'Month' THEN dateadd(mm,datediff(mm,0,DB.[log_date]),0)
        WHEN 'Year'  THEN dateadd(yy,datediff(yy,0,DB.[log_date]),0)
        ELSE DB.[log_date] END ;

我传递的参数是:

  1. '周'
  2. '2016-05-16'
  3. '2016-05-22'
  4. 6044
  5. 6044
  6. '周'

注意:此查询在 SQL Management Studio 中运行没有错误。

【问题讨论】:

  • 错误是不言自明的:您选择的列不在GROUP BY 子句中或者是一个聚合列(例如SUM(some_column))。解决这个问题,错误就会消失。
  • @TimBiegeleisen 我也知道您提到的错误原因。我不知道我在语法中做错了什么。
  • 能否提供填写参数的查询?查询失败时CASE ?会变成什么?
  • @destination-data 我将 Case 中的“Week”设置为参数。
  • 如果您将大部分查询移动到包含 case 语句的子选择中,然后对子选择结果进行分组和聚合,错误会消失吗?我尽量不要在 group by 和 select 中复制大的 case 语句,因为稍后代码可能会漂移。

标签: java sql sql-server


【解决方案1】:

根据此处的要求,在分组之前使用子查询对您的代码进行了修改。由于我没有您的数据库,因此我无法保证所有内容都完全正确,但请尝试一下。

当您的分组依据具有将在选择中重复的复杂逻辑时,我建议始终使用子查询。有些人可能会放弃第二个条件,只要分组依据有复杂的逻辑就说。

SELECT  sub.Site_Code, sub.[Site], sub.[Utility], sub.[Meter Type],
        sub.[log_date],
        SUM(sub.[value]) as [value],
        SUM(sub.[Cost]) as [cost],
        SUM(sub.[CO]) as [CO],
        sub.[Meter Name], sub.[Units], sub.[Meter_ID],
        sub.[Parent], sub.[Meter_Description]
FROM    (
        SELECT EP.Site_Code AS [Site_Code], DB.[Site] AS [Site], DB.[Utility] AS [Utility], 
                CASE ? WHEN 'Raw' THEN dateadd(mi,datediff(mi,0,DB.[log_date]),0) 
                WHEN 'Hour'  THEN dateadd(hh,datediff(hh,0,DB.[log_date]),0)
                WHEN 'Day'   THEN dateadd(dd,datediff(dd,0,DB.[log_date]),0)
                WHEN 'Week'  THEN dateadd(wk,datediff(wk,0,DB.[log_date]),0)
                WHEN 'Month' THEN dateadd(mm,datediff(mm,0,DB.[log_date]),0)
                WHEN 'Year'  THEN dateadd(yy,datediff(yy,0,DB.[log_date]),0)                                                     
                ELSE DB.[log_date]
                END AS [log_date],
                CASE WHEN DB.[value] >= 0 THEN DB.[value] ELSE 0 END AS [value],
                CASE WHEN DB.[Cost] >=0 THEN DB.[cost] ELSE 0 END AS [Cost],
                CASE WHEN DB.[CO2] >=0 THEN DB.[CO2] ELSE 0 END AS [CO],
                MT.[Meter_type_name] AS [Meter Type],
                MN.[Meter_Name] AS [Meter Name],
                U.[Unit_Name] AS [Units],
                EP.EnergyPoint_ID AS [Meter_ID],
                EP.Parent_ID AS [Parent],
                EP.Meter_Description AS [Meter_Description] 
        FROM [dbo].[JOHN_Dashboard] DB
        INNER JOIN [dbo].[EnergyPoints] EP ON DB.[EnergyPoint_ID] = EP.[EnergyPoint_ID] 
        INNER JOIN [dbo].[Meter_Types] MT ON MT.[Meter_Type_ID] = EP.[Meter_Type_ID]
        INNER JOIN [dbo].[Meter_Names] MN ON MN.[Meter_Name_ID] = EP.[Meter_Name_ID]
        INNER JOIN [dbo].[Units] U ON U.[Unit_ID] = EP.[Unit_id]
        WHERE [log_date] >= ? AND [Log_Date] < DATEADD(DAY, 1, ?)
        AND ( ? IS NULL OR EP.Energypoint_ID = ?)
        ) sub
GROUP BY sub.Site_Code, sub.[Site], sub.[Utility], sub.[Meter Type],           
        sub.[Meter Name], sub.[Units], sub.[Meter_ID],
        sub.[Parent], sub.[Meter_Description], sub.[log_date];

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-22
    • 2022-10-06
    • 2020-10-26
    相关资源
    最近更新 更多