SQL 服务器:具有内部 SELECT 和子 SELECT 的 SUM()。每次都出错
SQL Server: SUM() with internal SELECT and sub SELECT. Error every time
问题已改写
我 在 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
而且我不断收到此错误。
Cannot perform an aggregate function on an expression containing an
aggregate or a subquery.
我正在尝试获取 outside/bigger SELECT 中的总行数以及 TOTUCONT 中唯一容器计数的总数。
我做错了什么?
这是更大的 SQL 查询,以说明我关于 GROUP BY 和聚合函数中的子查询的观点,如 SUM():
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) + ')'
以上无论如何都不起作用,因为我试图通过将 "column" SELECT 分离到它自己的 JOIN 查询中来解决这个问题,但现在我得到了这个:
The multi-part identifier "gl.MessageID" could not be bound.
这意味着 LEFT JOIN (SELECT...) 无效?
再次感谢
更新 2
这里有一个数据样本来进一步解释:
所以你可以看到我想要的结果,TOTCONT 加起来为“4”。这很简单 - 只需计算行数,但 TOTUCONT 只计算容器 ID 一次。
试试这个,
(SELECT SUM(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,
我认为你可以将其简化为:
(SELECT COUNT(gl2.ContainerID)
FROM dbo.tblEDIGoodsLines gl2
WHERE gl2.VisitID = gl.VisitID AND
gl2.MessageID = gl.MessageID AND
gl2.BillOfLading = gl.BillOfLading
) as TotalContainers,
备注:
- 外面的
SUM()
是不必要的。您可以在子查询中进行聚合。
- 不需要两级子查询。
-
GROUP BY
是不必要的。没有 GROUP BY
的聚合查询总是 returns 恰好一行,这就是您想要的标量子查询。
根据您查询的其余部分,这在您的完整查询中可能仍然不起作用。如果是这种情况,那么您应该提出一个 new 问题,其中包含示例数据、所需结果和(的简化版本)不起作用的查询。
改为:
SUM(a.CONT_TOT) as TotalContainers
FROM (
SELECT 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,
根据代码的用途,您可能需要在末尾使用括号。
我从 SELECT 列表中删除了额外的列,因为获取 SUM() 不需要它们(除非您需要它们来做其他事情?)。
编辑
从最后一个 JOIN 中删除 WHERE 子句:
WHERE gl2.MessageID = gl.MessageID
AND gl2.VisitID = gl.VisitID
and gl2.BillOfLading = gl.billoflading
and gl2.description = gl.description
这些条件适用于 ON 子句。
尝试重构代码使其更像这样(正如我之前评论的那样)。它还可能有助于解决您正在处理的其他问题:
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;
问题已改写
我 在 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
而且我不断收到此错误。
Cannot perform an aggregate function on an expression containing an aggregate or a subquery.
我正在尝试获取 outside/bigger SELECT 中的总行数以及 TOTUCONT 中唯一容器计数的总数。
我做错了什么?
这是更大的 SQL 查询,以说明我关于 GROUP BY 和聚合函数中的子查询的观点,如 SUM():
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) + ')'
以上无论如何都不起作用,因为我试图通过将 "column" SELECT 分离到它自己的 JOIN 查询中来解决这个问题,但现在我得到了这个:
The multi-part identifier "gl.MessageID" could not be bound.
这意味着 LEFT JOIN (SELECT...) 无效?
再次感谢
更新 2
这里有一个数据样本来进一步解释:
所以你可以看到我想要的结果,TOTCONT 加起来为“4”。这很简单 - 只需计算行数,但 TOTUCONT 只计算容器 ID 一次。
试试这个,
(SELECT SUM(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,
我认为你可以将其简化为:
(SELECT COUNT(gl2.ContainerID)
FROM dbo.tblEDIGoodsLines gl2
WHERE gl2.VisitID = gl.VisitID AND
gl2.MessageID = gl.MessageID AND
gl2.BillOfLading = gl.BillOfLading
) as TotalContainers,
备注:
- 外面的
SUM()
是不必要的。您可以在子查询中进行聚合。 - 不需要两级子查询。
-
GROUP BY
是不必要的。没有GROUP BY
的聚合查询总是 returns 恰好一行,这就是您想要的标量子查询。
根据您查询的其余部分,这在您的完整查询中可能仍然不起作用。如果是这种情况,那么您应该提出一个 new 问题,其中包含示例数据、所需结果和(的简化版本)不起作用的查询。
改为:
SUM(a.CONT_TOT) as TotalContainers
FROM (
SELECT 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,
根据代码的用途,您可能需要在末尾使用括号。
我从 SELECT 列表中删除了额外的列,因为获取 SUM() 不需要它们(除非您需要它们来做其他事情?)。
编辑
从最后一个 JOIN 中删除 WHERE 子句:
WHERE gl2.MessageID = gl.MessageID
AND gl2.VisitID = gl.VisitID
and gl2.BillOfLading = gl.billoflading
and gl2.description = gl.description
这些条件适用于 ON 子句。
尝试重构代码使其更像这样(正如我之前评论的那样)。它还可能有助于解决您正在处理的其他问题:
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;