【问题标题】:SQL Error "Cannot perform an aggregate function on an expression containing an aggregate or a sub query."SQL 错误“无法对包含聚合或子查询的表达式执行聚合函数。”
【发布时间】:2016-08-15 19:24:12
【问题描述】:

我正在 Oracle 中执行此查询。我已经添加了我的数据和返回结果的屏幕截图,但返回的结果是错误的。它返回 1,但应该返回 0.52。因为客户(见附件截图)有代码 1,2,4,31,对于 1,2,4,他应该得到 0.70 值,对于 31,他应该得到 0.75,然后乘法后返回的结果应该是 0.52 而不是 1 . 我真的被困在这里了。请帮我。我会非常感谢你。

这是我的查询。我真正想做的是我想根据他们得到的代码计算给每个客户的积分值。

如果客户的代码 = 1,那么他将获得 0.70 分,如果他也有代码 = 2 和 4,那么我不想给他额外的代码 2 和 4 的 0.70。

让我简单点。如果客户拥有所有这些代码 1、2、4,那么他一次只能获得 0.70 积分,但如果他只有代码 4,那么他将获得 0.90,但如果他也获得代码 31,那么他将获得额外的 0.75有代码 31。现在有意义吗?

       SELECT 
       RM_LIVE.EMPLOYEE.EMPNO, RM_LIVE.EMPNAME.FIRSTNAME,
       RM_LIVE.EMPNAME.LASTNAME, RM_LIVE.CRWBASE.BASE ,RM_LIVE.CRWCAT.crwcat AS "Rank",
       nvl(nullif(MAX(CASE WHEN RM_LIVE.CRWSPECFUNC.IDCRWSPECFUNC IN (29,721) THEN 0.25 ELSE 1 END),0),1) *
       nvl(nullif(MAX(CASE WHEN RM_LIVE.CRWSPECFUNC.IDCRWSPECFUNC IN (31,723) THEN 0.75 ELSE 1 END),0),1) *
       nvl(nullif(MAX(CASE WHEN RM_LIVE.CRWSPECFUNC.IDCRWSPECFUNC = 861 THEN 0.80 ELSE 1 END),0),1) *
       nvl(nullif(MAX(CASE WHEN RM_LIVE.CRWSPECFUNC.IDCRWSPECFUNC IN (17,302,16) THEN 0.85 ELSE 1 END),0),1) *
       nvl(nullif(MAX(CASE WHEN RM_LIVE.CRWSPECFUNC.IDCRWSPECFUNC IN (3,7) THEN 0.90 ELSE 1 END),0),1)*
       nvl(nullif(MAX(CASE WHEN RM_LIVE.CRWSPECFUNC.IDCRWSPECFUNC IN (921,301,30,722,601,581) THEN 0.50 ELSE 1 END),0),1) *
       nvl(nullif(MAX(CASE WHEN RM_LIVE.CRWSPECFUNC.IDCRWSPECFUNC IN (2,1, 4) THEN 0.70 ELSE 1 END),0),1) *
       nvl(nullif(MIN(CASE WHEN RM_LIVE.CRWSPECFUNC.IDCRWSPECFUNC  IN (1,2) then 0 else 1 END) * 
                  MAX(CASE WHEN RM_LIVE.CRWSPECFUNC.IDCRWSPECFUNC  IN (4) then 0.20 else 0 END),0),1) AS "FTE VALUE"

     FROM RM_LIVE.EMPBASE,
     RM_LIVE.EMPLOYEE,
     RM_LIVE.CRWBASE,
     RM_LIVE.EMPNAME,
     RM_LIVE.CRWSPECFUNC,
     RM_LIVE.EMPSPECFUNC,RM_LIVE.EMPQUALCAT,RM_LIVE.CRWCAT
       where RM_LIVE.EMPBASE.IDEMPNO = RM_LIVE.EMPLOYEE.IDEMPNO
        AND RM_LIVE.EMPBASE.IDCRWBASE = RM_LIVE.CRWBASE.IDCRWBASE
         AND RM_LIVE.EMPLOYEE.IDEMPNO = RM_LIVE.EMPNAME.IDEMPNO 
          AND RM_LIVE.EMPSPECFUNC.IDCRWSPECFUNC =RM_LIVE.CRWSPECFUNC.IDCRWSPECFUNC  
           AND RM_LIVE.EMPSPECFUNC.IDEMPNO =RM_LIVE.EMPLOYEE.IDEMPNO
            AND  RM_LIVE.EMPQUALCAT.IDEMPNO=RM_LIVE.EMPLOYEE.IDEMPNO 
             AND  RM_LIVE.CRWCAT.IDCRWCAT = RM_LIVE.EMPQUALCAT.IDCRWCAT
              AND RM_LIVE.CRWCAT.crwcat IN ('CP','FO','CM','MC')
               AND RM_LIVE.CRWBASE.BASE <> 'XYZ'
                AND RM_LIVE.CRWSPECFUNC.IDCRWSPECFUNC IN  
                ('921','2' ,'1','301','17','4','3','7','302' ,'861','31',
                 '723','30','722 ','29 ','721','16','601','581')  
                  AND RM_LIVE.EMPBASE.STARTDATE <= SYSDATE
                   AND RM_LIVE.EMPBASE.ENDDATE >= SYSDATE
                    AND RM_LIVE.EMPSPECFUNC.STARTDATE <= SYSDATE
                     AND RM_LIVE.EMPSPECFUNC.ENDDATE >= SYSDATE
                      AND RM_LIVE.EMPNAME.FROMDATE <=SYSDATE
                       AND RM_LIVE.EMPQUALCAT.STARTDATE <= SYSDATE
                        AND RM_LIVE.EMPQUALCAT.ENDDATE >= SYSDATE
       GROUP BY RM_LIVE.EMPLOYEE.EMPNO, RM_LIVE.EMPNAME.FIRSTNAME,
       RM_LIVE.EMPNAME.LASTNAME, RM_LIVE.CRWBASE.BASE,RM_LIVE.CRWCAT.crwcat;

【问题讨论】:

  • “给出错误”:什么样的错误?还要修正你的标题,使其更具体。
  • 可以添加错误信息吗?
  • 什么样的错误?
  • 在名称旁边保留逗号
  • 现在添加逗号后,该错误消失了,但现在面临另一个错误(无法对包含聚合或子查询的表达式执行聚合函数。)。

标签: sql sql-server sql-server-2008 sql-server-2005 sql-server-2008-r2


【解决方案1】:

根据想要的结果评论,试试这个

SELECT [id]
  ,[name]
  , r = max(CASE WHEN [code]  IN (1,2,4) then 100 else 0 end)
    + max(CASE WHEN [code] IN (8) then 80 else 0 end)
  FROM 
    -- your table here
    (values (1, 'ali',4)
            ,(1, 'ali',1)
            ,(1, 'ali',8)
    ) as t(id, name,code)
  GROUP BY id, name;

编辑另一个排除某些东西的故事。 1,2,4 中的任何一个都给 100 加,如果它只有 4 没有 (1,2) 加 400。

SELECT [id]
  ,[name]
  , r = max(CASE WHEN [code]  IN (1,2,4) then 100 else 0 end)
    + min(CASE WHEN [code]  IN (1,2) then 0 else 1 end) 
        * max(CASE WHEN [code]  IN (4) then 400 else 0 end)
    + max(CASE WHEN [code] IN (8) then 80 else 0 end)
  FROM 
    -- your table here
    (values (1, 'ali',4)
            ,(1, 'ali',1)
            ,(1, 'ali',8)
            ,(2, 'ali',4)
            ,(2, 'ali',8)
    ) as t(id, name,code)
  GROUP BY id, name;

编辑 2 如果需要乘分数,请将 + 替换为 * 并将 0 转换为 1。

SELECT [id]
  ,[name]
  ,r = isnull(nullif(
        max(CASE WHEN [code]  IN (1,2,4) then 100 else 0 end)
      ,0),1)
    * isnull(nullif(
       min(CASE WHEN [code]  IN (1,2) then 0 else 1 end) 
        * max(CASE WHEN [code]  IN (4) then 400 else 0 end)
      ,0),1)
    * isnull(nullif(
        max(CASE WHEN [code] IN (8) then 80 else 0 end)
      ,0),1)
  FROM 
    -- your table here
    (values (1, 'ali',4)
            ,(1, 'ali',1)
            ,(1, 'ali',8)
            ,(2, 'ali',4)
            ,(2, 'ali',8)
    ) as t(id, name,code)
  GROUP BY id, name;

【讨论】:

  • 你能告诉我如果另一个客户只有code = 4那么我想给他500分。我的意思是,如果他没有代码 1 和 2,而只有代码 4。它的查询是什么?谢谢
  • 根据这个查询,即使他只有代码 4,他也会得到 100 分,但我想给他只有代码 4 的 500 分。这对你有意义吗?
  • 如果他有 1,2 和 4 怎么办? 100+ 500?
  • 如果他有 1,2 和 4 则为 100,但如果他只有 4 则为 500。
  • 如果他有 1,2 和 4,那么它将是 100,但如果他只有 4,那么它将是 500。
【解决方案2】:

您已经从 testcode 表中进行选择 - 无需在 CASE 表达式中执行任何子查询 - 只需使用以下代码:

SELECT 
    [id], [name],
    SUM(CASE 
           WHEN [code] IN (1, 2, 4) 
               THEN 100 
           WHEN [code] = 8
               THEN 80
        END) AS [total] 
FROM 
    [Test].[dbo].[testcode] AS t 
GROUP BY 
    id, name

【讨论】:

    【解决方案3】:

    您在计算总和之前漏掉了一个逗号 (,)。

    所以你的代码应该是:

    SELECT [id]
      ,[name]
      ,SUM(CASE WHEN (SELECT [code] 
                       FROM [Test].[dbo].[testcode] as ts 
                       WHERE ts.id = t.id) IN (1,2,4) 
                then 100 
                else 10 
               end) as "total" 
      FROM [Test].[dbo].[testcode] as t 
      GROUP BY id, name
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多