我的 SQL 怎么了?

Whats wrong with my SQL?

我必须编辑存储过程并添加按部门整理结果的功能。编辑后收到错误:

Msg 8120, Level 16, State 1, Procedure acc_qry_profit_loss_this_year_by_dept, Line 543 Column '#tmp_rsl.department' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

我认为错误不在第 543 行,或者可能只是我的眼睛。 这是从第 485 行到第 557 行开始的代码:

-- Blank line
  INSERT INTO #tmp_rsl(acc_id,parent_code,acc_code,description,acclevel,
    yr_balance,ly_balance,mn_balance,lm_balance,rsl_type,show_line)
  SELECT 0,'','' as acc_code,'' as acc_name,1,0,0,0,0,'BLANK_LINE' as rsl_type,0 as show_line

    --OI    Other Income
  SET @rsl_acc_type='OI'
  INSERT INTO #tmp_rsl(acc_id,department,department_name,parent_code,acc_code,description,acclevel,
    yr_balance,ly_balance,mn_balance,lm_balance,rsl_type,show_line)
  SELECT acc_id,department,department_name,parent_code,acc_code,acc_name,acclevel,
    ISNULL(yr_credit,0)-ISNULL(yr_debit,0),
    ISNULL(ly_credit,0)-ISNULL(ly_debit,0),
    ISNULL(mn_credit,0)-ISNULL(mn_debit,0),ISNULL(lm_credit,0)-ISNULL(lm_debit,0),
    (CASE WHEN attribute=99 THEN 'CAT_HEAD' WHEN attribute=0 THEN 'FOLDER' ELSE 'DETAIL' END) as rsl_type,0
  FROM #tmp_acc_list WHERE acctype=@rsl_acc_type AND acclevel=1 

  INSERT INTO #tmp_rsl(acc_id,department,department_name,parent_code,acc_code,description,acclevel,
    yr_balance,ly_balance,mn_balance,lm_balance,rsl_type,show_line)
  SELECT acc_id,department,department_name,parent_code,acc_code,acc_name,acclevel,
    ISNULL(yr_credit,0)-ISNULL(yr_debit,0),
    ISNULL(ly_credit,0)-ISNULL(ly_debit,0),
    ISNULL(mn_credit,0)-ISNULL(mn_debit,0),ISNULL(lm_credit,0)-ISNULL(lm_debit,0),
    (CASE WHEN attribute=99 THEN 'CAT_HEAD' WHEN attribute=0 THEN 'FOLDER' ELSE 'DETAIL' END) as rsl_type,0
  FROM #tmp_acc_list WHERE acctype=@rsl_acc_type AND acclevel<>1 order by department,acc_code

  INSERT INTO #tmp_rsl(acc_id,department,department_name,parent_code,acc_code,description,acclevel,
    yr_balance,ly_balance,mn_balance,lm_balance,rsl_type,show_line)
  SELECT 0,department,department_name,'','' as acc_code,'' as acc_name,acclevel,
    ISNULL(yr_credit,0)-ISNULL(yr_debit,0),
    ISNULL(ly_credit,0)-ISNULL(ly_debit,0),
    ISNULL(mn_credit,0)-ISNULL(mn_debit,0),ISNULL(lm_credit,0)-ISNULL(lm_debit,0),
    'CAT_SUMM' as rsl_type,1
  FROM #tmp_acc_list WHERE acctype=@rsl_acc_type AND acclevel=1

  --EX  Expenses
  SET @rsl_acc_type='EX'
  INSERT INTO #tmp_rsl(acc_id,department,department_name,parent_code,acc_code,description,acclevel,
    yr_balance,ly_balance,mn_balance,lm_balance,rsl_type,show_line)
  SELECT acc_id,department,department_name,parent_code,acc_code,acc_name,acclevel,
    ISNULL(yr_debit,0)-ISNULL(yr_credit,0),
    ISNULL(ly_debit,0)-ISNULL(ly_credit,0),
    ISNULL(mn_debit,0)-ISNULL(mn_credit,0),ISNULL(lm_debit,0)-ISNULL(lm_credit,0),
    (CASE WHEN attribute=99 THEN 'CAT_HEAD' WHEN attribute=0 THEN 'FOLDER' ELSE 'DETAIL' END) as rsl_type,0
  FROM #tmp_acc_list WHERE acctype=@rsl_acc_type AND acclevel=1 

  INSERT INTO #tmp_rsl(acc_id,department,department_name,parent_code,acc_code,description,acclevel,
    yr_balance,ly_balance,mn_balance,lm_balance,rsl_type,show_line)
  SELECT acc_id,department,department_name,parent_code,acc_code,acc_name,acclevel,
    ISNULL(yr_debit,0)-ISNULL(yr_credit,0),
    ISNULL(ly_debit,0)-ISNULL(ly_credit,0),
    ISNULL(mn_debit,0)-ISNULL(mn_credit,0),ISNULL(lm_debit,0)-ISNULL(lm_credit,0),
    (CASE WHEN attribute=99 THEN 'CAT_HEAD' WHEN attribute=0 THEN 'FOLDER' ELSE 'DETAIL' END) as rsl_type,0
  FROM #tmp_acc_list WHERE acctype=@rsl_acc_type AND acclevel<>1 order by department,acc_code

  INSERT INTO #tmp_rsl(acc_id,department,department_name,parent_code,acc_code,description,acclevel,
    yr_balance,ly_balance,mn_balance,lm_balance,rsl_type,show_line)
  SELECT 0,department,department_name,'','' as acc_code,'' as acc_name,acclevel,
    ISNULL(yr_debit,0)-ISNULL(yr_credit,0),
    ISNULL(ly_debit,0)-ISNULL(ly_credit,0),
    ISNULL(mn_debit,0)-ISNULL(mn_credit,0),ISNULL(lm_debit,0)-ISNULL(lm_credit,0),
    'CAT_SUMM' as rsl_type,1
  FROM #tmp_acc_list WHERE acctype=@rsl_acc_type AND acclevel=1

  INSERT INTO #tmp_rsl(acc_id,department,department_name,parent_code,acc_code,description,acclevel,
    yr_balance,ly_balance,mn_balance,lm_balance,rsl_type,show_line)
  SELECT 0,department,department_name,'','NP' as acc_code,'NET PROFIT/(LOSS)' as acc_name,1,
    SUM((CASE WHEN acc_code='CS' OR acc_code='EX' THEN -1*yr_balance ELSE yr_balance END)),
    SUM((CASE WHEN acc_code='CS' OR acc_code='EX' THEN -1*ly_balance ELSE ly_balance END)),
    SUM((CASE WHEN acc_code='CS' OR acc_code='EX'  THEN -1*mn_balance ELSE mn_balance END)),
    SUM((CASE WHEN acc_code='CS' OR acc_code='EX'  THEN -1*lm_balance ELSE lm_balance END)),
    'CAT_NETPROFIT' as rsl_type,1
  FROM #tmp_rsl WHERE rsl_type='CAT_HEAD'

那么,如果我展示的代码部分存在错误,是否有人可以指出可能的错误?

我正在使用 Microsoft 的 SQL Server Management Studio 2014。

您正在查询中做类似的事情...

select EmpId, count(LocationId)
from Employee

或者与之相反的东西

select EmpId, LocationId
from Employee
Group by EmpId

在这两种情况下都会引发以下错误

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

如果您仔细查看您的查询,您会使用一些聚合函数,例如 SUM(在您上一个查询中)等。

错误中的行号通常具有误导性,尤其是对于存储过程。它可以很好地指示错误出现在查询的哪一部分(尤其是如果有数百行),但您应该关注错误的描述。

Column '#tmp_rsl.department' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

select 列表包含聚合函数或分组依据子句中不包含的字段(部门)。 只有一个查询带有聚合函数,而且它也没有 group by 子句。

  INSERT INTO #tmp_rsl(acc_id,department,department_name,parent_code,acc_code,description,acclevel,
    yr_balance,ly_balance,mn_balance,lm_balance,rsl_type,show_line)
  SELECT 0,department,department_name,'','NP' as acc_code,'NET PROFIT/(LOSS)' as acc_name,1,
    SUM((CASE WHEN acc_code='CS' OR acc_code='EX' THEN -1*yr_balance ELSE yr_balance END)),
    SUM((CASE WHEN acc_code='CS' OR acc_code='EX' THEN -1*ly_balance ELSE ly_balance END)),
    SUM((CASE WHEN acc_code='CS' OR acc_code='EX'  THEN -1*mn_balance ELSE mn_balance END)),
    SUM((CASE WHEN acc_code='CS' OR acc_code='EX'  THEN -1*lm_balance ELSE lm_balance END)),
    'CAT_NETPROFIT' as rsl_type,1
  FROM #tmp_rsl WHERE rsl_type='CAT_HEAD'

此查询的 SUM 部分是聚合函数。 您需要在 FROM 之后添加 GROUP BY。 可能需要几个部门,dept_name, acc_code包含在聚合函数

您上次查询

   SELECT 
         0,
         department,
         department_name,
         '',
          'NP' as acc_code,
         'NET PROFIT/(LOSS)' as acc_name,1,
         SUM((CASE WHEN acc_code='CS' OR acc_code='EX' THEN -1*yr_balance ELSE yr_balance END)),
         SUM((CASE WHEN acc_code='CS' OR acc_code='EX' THEN -1*ly_balance ELSE ly_balance END)),
         SUM((CASE WHEN acc_code='CS' OR acc_code='EX'  THEN -1*mn_balance ELSE mn_balance END)),
         SUM((CASE WHEN acc_code='CS' OR acc_code='EX'  THEN -1*lm_balance ELSE lm_balance END)),
         'CAT_NETPROFIT' as rsl_type,
         1 
   FROM 
     #tmp_rsl WHERE rsl_type='CAT_HEAD'

是问题所在。您使用像 'department' 这样的列而没有任何聚合,然后您有由聚合计算的列(如总和)。你不能混合这些列。您没有聚合,所有聚合或没有任何聚合的列必须是您分组的一部分,如下所示:

   SELECT 
         0,
         department,
         department_name,
         '',
          'NP' as acc_code,
         'NET PROFIT/(LOSS)' as acc_name,1,
         SUM((CASE WHEN acc_code='CS' OR acc_code='EX' THEN -1*yr_balance ELSE yr_balance END)),
         SUM((CASE WHEN acc_code='CS' OR acc_code='EX' THEN -1*ly_balance ELSE ly_balance END)),
         SUM((CASE WHEN acc_code='CS' OR acc_code='EX'  THEN -1*mn_balance ELSE mn_balance END)),
         SUM((CASE WHEN acc_code='CS' OR acc_code='EX'  THEN -1*lm_balance ELSE lm_balance END)),
         'CAT_NETPROFIT' as rsl_type,
         1 
   FROM 
     #tmp_rsl WHERE rsl_type='CAT_HEAD'
   GROUP BY department, department_name

问题在于您在最后的插入语句中使用了聚合函数 (SUM)。您可能会发现 this 文章很有用..

同时..

INSERT INTO #tmp_rsl(acc_id,department,department_name,parent_code,acc_code,description,acclevel,yr_balance,ly_balance,mn_balance,lm_balance,rsl_type,show_line)
SELECT 0,department,department_name,'','NP' as acc_code,'NET PROFIT/(LOSS)' as acc_name,1,
  SUM((CASE WHEN acc_code='CS' OR acc_code='EX' THEN -1*yr_balance ELSE yr_balance END)),
  SUM((CASE WHEN acc_code='CS' OR acc_code='EX' THEN -1*ly_balance ELSE ly_balance END)),
  SUM((CASE WHEN acc_code='CS' OR acc_code='EX'  THEN -1*mn_balance ELSE mn_balance END)),
  SUM((CASE WHEN acc_code='CS' OR acc_code='EX'  THEN -1*lm_balance ELSE lm_balance END)),
  'CAT_NETPROFIT' as rsl_type,1
FROM #tmp_rsl WHERE rsl_type='CAT_HEAD'

应该是

INSERT INTO #tmp_rsl(acc_id,department,department_name,parent_code,acc_code,description,acclevel,yr_balance,ly_balance,mn_balance,lm_balance,rsl_type,show_line)
SELECT 0,department,department_name,'','NP' as acc_code,'NET PROFIT/(LOSS)' as acc_name,1,
  SUM((CASE WHEN acc_code='CS' OR acc_code='EX' THEN -1*yr_balance ELSE yr_balance END)),
  SUM((CASE WHEN acc_code='CS' OR acc_code='EX' THEN -1*ly_balance ELSE ly_balance END)),
  SUM((CASE WHEN acc_code='CS' OR acc_code='EX'  THEN -1*mn_balance ELSE mn_balance END)),
  SUM((CASE WHEN acc_code='CS' OR acc_code='EX'  THEN -1*lm_balance ELSE lm_balance END)),
  'CAT_NETPROFIT' as rsl_type,1
FROM #tmp_rsl WHERE rsl_type='CAT_HEAD'
GROUP BY department,department_name