简体   繁体   中英

How to use SQL Case in Group by Clause?

I'm using SQL Case in my select and in group by clause and I'm working in JAVA. Whenever I execute my java program it says:

Column 'dbo.JOHN_Dashboard.Log_Date' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

My Query is:

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 ;

The parameters i'm passing are:

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

Note: This query runs without error in SQL Management Studio.

As requested here is a reworked version of your code using a sub-query before grouping. Since I don't have your database I can't guarantee that I have everything exactly right but give this a try.

I recommend always using a sub-query when your group by has complicated logic that will be repeated in the select. Some people would probably drop the second criteria and just say whenever the group by has complicated logic.

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];

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM