SQL Server:带有内部 SELECT 和子 SELECT 的 SUM()。每次都出错

Fandango68

问题重述

在 SQL 语句中以下列定义,它有自己的GROUP BY......

    SUM((SELECT a.CONT_TOT
     FROM  (SELECT   gl2.VisitID, gl2.MessageID, gl2.BillOfLading, COUNT(gl2.ContainerID) AS CONT_TOT
            FROM     dbo.tblEDIGoodsLines AS gl2
            WHERE    gl2.VisitID = gl.VisitID AND gl2.MessageID = gl.MessageID AND gl2.BillOfLading = gl.BillOfLading
            GROUP BY gl2.VisitID, gl2.MessageID, gl2.BillOfLading) AS a)) as TotalContainers,    

...etc

我不断收到这个错误。

无法对包含聚合或子查询的表达式执行聚合函数。

我正在尝试获取外部/更大的 SELECT 中的总行数,以及 TOTUCONT 中 UNIQUE 容器的总数。

我究竟做错了什么?

这是更大的 SQL 查询,以说明我对 SUM() 等聚合函数中的 GROUP BY 和子查询的观点:

SELECT
    gl.MessageID,
    gl.BillOfLading,
    gl.[Description],
    CASE WHEN e.PortID = 9 THEN 'Export'
      WHEN e.PortID = 11 THEN 'Import'
      ELSE 'ERROR'
    END AS Direction,
    CASE WHEN ctypes.ID IS NOT NULL
         THEN ctypes.ContainerSizeType 
         ELSE 'OTH'
    END AS CSizeType,
    ctypes.Length_ft + 'ft ' + ctypes.Height_ft + 'ft - ' + ctypes.Characteristics + ' (' + COALESCE(ctypes.Codes1995, ctypes.Codes1984) + ')' AS ContainerType,
    COUNT(gl.ContainerID) AS TOTCONT,
    SUM(a.CTOTAL) AS TOTUCONT
FROM tblEDIGoodsLines AS gl 
    INNER JOIN tblEDIEquipmentLines AS el 
        ON el.MessageID = gl.MessageID AND
           el.ContainerID = gl.ContainerID
    INNER JOIN tblEDI AS e
        ON CHARINDEX(e.MessageID, gl.MessageID) > 0 AND
           e.VisitID = gl.VisitID AND
           CHARINDEX('EXCEL', e.MessageRelease) = 0 AND
           e.Status = 1
    LEFT JOIN tblContainerTypesISO6346 AS ctypes 
        ON ctypes.Codes1984 = el.SizeAndType OR 
           ctypes.Codes1995 = el.SizeAndType
    LEFT JOIN (SELECT gl2.MessageID, gl2.VisitID, gl2.BillOfLading, gl2.description, COUNT(DISTINCT gl2.ContainerID) AS CTOTAL
              FROM tblEDIGoodsLines AS gl2 
              WHERE gl2.MessageID = gl.MessageID 
                AND gl2.VisitID = gl.VisitID 
                and gl2.BillOfLading = gl.billoflading 
                and gl2.description = gl.description
              GROUP BY gl2.MessageID, gl2.VisitID, gl2.BillOfLading, gl2.description) AS a
        ON a.MessageID = gl.MessageID AND a.VisitID = gl.VisitID AND a.BillOfLading = gl.billoflading AND a.description = gl.description
WHERE gl.Status = 1
  AND gl.VisitID = 22987
GROUP BY
    gl.MessageID,
    gl.BillOfLading,
    gl.[Description],
    CASE WHEN e.PortID = 9 THEN 'Export'
         WHEN e.PortID = 11 THEN 'Import'
         ELSE 'ERROR'
    END,
    CASE WHEN ctypes.ID IS NOT NULL
         THEN ctypes.ContainerSizeType 
         ELSE 'OTH'
    END,
    ctypes.Length_ft + 'ft ' + ctypes.Height_ft + 'ft - ' + ctypes.Characteristics + ' (' + COALESCE(ctypes.Codes1995, ctypes.Codes1984) + ')'

以上无论如何都不起作用,因为我试图通过将“列” SELECT 分离到它自己的 JOIN 查询中来解决这个问题,但现在我明白了:

无法绑定多部分标识符“gl.MessageID”。

所以这意味着,LEFT JOIN (SELECT...) 是无效的?

再次感谢

更新 2

下面是一个数据样本来进一步解释:

在此处输入图片说明

所以你可以看到我想要的结果,TOTCONT 加起来为“4”。这很简单 - 只需计算行数,但 TOTUCONT 只计算容器 ID 一次。

布鲁斯斯基奥

尝试将代码重构为更像这样(正如我之前评论过的)。它还可能有助于解决您正在处理的其他问题:

with cte_ctotal
as (
    select gl2.MessageID,
        gl2.VisitID,
        gl2.BillOfLading,
        gl2.description,
        COUNT(distinct gl2.ContainerID) as CTOTAL
    from tblEDIGoodsLines as gl2
    group by gl2.MessageID,
        gl2.VisitID,
        gl2.BillOfLading,
        gl2.description
    ),
cte_containers
as (
    select
    a.ContainerID,
    gl.MessageID,
    gl.VisitID,
    gl.BillOfLading,
    gl.Description,
    case 
        when e.PortID = 9
            then 'Export'
        when e.PortID = 11
            then 'Import'
        else 'ERROR'
        end as Direction,
    case 
        when ctypes.ID is not null
            then ctypes.ContainerSizeType
        else 'OTH'
        end as CSizeType,
    ctypes.Length_ft + 'ft ' + ctypes.Height_ft + 'ft - ' + ctypes.Characteristics + ' (' + COALESCE(ctypes.Codes1995, ctypes.Codes1984) + ')' as ContainerType,
    from tblEDIGoodsLines gl
    inner join tblEDIEquipmentLines el on el.MessageID = gl.MessageID
                                        and el.ContainerID = gl.ContainerID
    inner join tblEDI e on CHARINDEX(e.MessageID, gl.MessageID) > 0
                        and e.VisitID = gl.VisitID
                        and CHARINDEX('EXCEL', e.MessageRelease) = 0
                        and e.status = 1
    left join tblContainerTypesISO6346 ctypes on ctypes.Codes1984 = el.SizeAndType
                                              or ctypes.Codes1995 = el.SizeAndType
    where gl.status = 1
    and gl.VisitID = 22987
    )
select 
c.MessageID,
c.BillOfLading,
c.Description,
c.Direction,
c.CSizeType,
c.ContainerType,
COUNT(c.ContainerID) as TOTCONT,
SUM(COALESCE(ct.CTOTAL,0)) as TOTUCONT
from cte_containers c
left join cte_ctotal ct on ct.MessageID = c.MessageID
                       and ct.VisitID = c.VisitID
                       and ct.BillOfLading = c.billoflading
                       and ct.description = c.description
group by c.MessageID,
    c.BillOfLading,
    c.Description,
    c.Direction,
    c.CSizeType,
    c.ContainerType;

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

具有多个AND和OR的SQL Select出错

来自分类Dev

SQL Select子查询和联接

来自分类Dev

SQL-带有子查询的SELECT语句

来自分类Dev

带有 SELECT AS 子查询的 Oracle SQL UNION

来自分类Dev

SQL if / else vs和/或in带有不同参数的select

来自分类Dev

SELECT和SELECT IN在sql中有什么区别?

来自分类Dev

带有子查询和GROUP BY的MySQL SELECT的性能

来自分类Dev

Oracle和SQL Server中的SELECT语句

来自分类Dev

SQL SELECT 和 JOIN

来自分类Dev

带有SELECT的MySQL SUM

来自分类Dev

SQL Server select for update

来自分类Dev

子查询中的SQL Select

来自分类Dev

带有not not子句的SQL select查询

来自分类Dev

SQL-SELECT带有多个where的AS

来自分类Dev

带有INNER JOIN的SQL SELECT错误

来自分类Dev

SQL Select中带有set语句

来自分类Dev

带有变量的 INSERT SELECT SQL 查询

来自分类Dev

带有计算的sql select语句

来自分类Dev

SQL Select-子查询具有多行

来自分类Dev

SQL select语句内部联接

来自分类Dev

在SQL select语句的不同列中使用sum()和count()

来自分类Dev

SQL查询-SUM中的SELECT

来自分类Dev

SQL查询-SUM中的SELECT

来自分类Dev

带有保存状态的 IF 语句中的 SELECT 和 SELECT

来自分类Dev

OrientDB SELECT和子查询

来自分类Dev

在SELECT查询中在SQL Server中合并日期和时间

来自分类Dev

SQL Server:使用select和其他参数插入

来自分类Dev

SELECT语句SQL SERVER中的LOOP和COUNT

来自分类Dev

使用带有.NET的单个命令将SQL INSERT和SELECT转换为Oracle