我需要在SQL Server 2008R2
中运行以下查询,但它会在查询的最小/最大聚合部分上抛出错误Incorrect Syntax near 'Order'
。
请注意,PONumber字段是一个字符串,但我们使用min/max
来识别works as expected
中的第一个和最后一个po以及2012
。
无论如何这可以解决?
WITH CTE AS
(
SELECT AuditId, DocMasterId, PoNumber,
RN_ASC = ROW_NUMBER() OVER (PARTITION BY DocMasterID
ORDER BY PoNumber ASC),
RN_DESC = ROW_NUMBER() OVER (PARTITION BY DocMasterID
ORDER BY PoNumber DESC),
CNT = COUNT(*) OVER (PARTITION BY DocMasterID),
F = MIN(PONumber) OVER (PARTITION BY DocMasterId
ORDER BY PoNumber ASC),
L = MAX(PONumber) OVER (PARTITION BY DocMasterId
ORDER BY PoNumber ASC)
FROM dbo.MyTable
WHERE (PONumber IS NOT NULL) AND (PONumber <> '') AND
(DocumentType = 'Purchase Order') and docmasterid > 0
)
答案 0 :(得分:0)
你的逻辑很奇怪。您正在获取列的累积最小值和最大值,该列是用于排序的列。所以:
DocMasterId
)。不需要累积分钟。DocMasterId
),它也恰好是当前值周期。不需要累积最大值。因此,您可以将逻辑重写为:
WITH CTE AS
(
SELECT AuditId, DocMasterId, PoNumber,
RN_ASC = ROW_NUMBER() OVER (PARTITION BY DocMasterID
ORDER BY PoNumber ASC),
RN_DESC = ROW_NUMBER() OVER (PARTITION BY DocMasterID
ORDER BY PoNumber DESC),
CNT = COUNT(*) OVER (PARTITION BY DocMasterID),
F = MIN(PONumber) OVER (PARTITION BY DocMasterId)
L = PoNumber
FROM dbo.MyTable
WHERE (PONumber IS NOT NULL) AND (PONumber <> '') AND
(DocumentType = 'Purchase Order') and docmasterid > 0
)
您可能真的想要:
F = MIN(PONumber) OVER (PARTITION BY DocMasterId)
L = PoNumber OVER (PARTITION BY DocMasterId)
但是第一个查询等同于您问题中的查询(好吧,如果PoNumber
可能是NULL
,那么在这种情况下,我必须更加思考它们是否完全等效)
答案 1 :(得分:0)
使用子查询的以下语句应该是等效的:
WITH myCTE(AuditId, DocMasterId, PoNumber) AS
(
SELECT AuditId, DocMasterId, PoNumber
FROM dbo.MyTable
WHERE (PONumber IS NOT NULL) AND (PONumber <> '') AND
(DocumentType = 'Purchase Order') and docmasterid > 0
),
CTE AS
(
SELECT AuditId, DocMasterId, PoNumber,
ROW_NUMBER() OVER (PARTITION BY DocMasterID
ORDER BY PoNumber ASC) AS RN_ASC,
ROW_NUMBER() OVER (PARTITION BY DocMasterID
ORDER BY PoNumber DESC) AS RN_DESC,
( SELECT COUNT(*) FROM myCTE t2 WHERE t2.DocMasterID = t.DocMasterID) AS CNT,
( SELECT MIN(PONumber) FROM myCTE t2 WHERE t2.DocMasterID = t.DocMasterID) AS F,
( SELECT MAX(PONumber) FROM myCTE t2 WHERE t2.DocMasterID = t.DocMasterID) AS L
FROM myCTE t
)
答案 2 :(得分:0)
这是我们最终用作解决方案的内容。不幸的是,任何试图提供帮助的人都无法提供最终答案,因为我们最终在查询中使用了另一个字段,即AuditId
。请注意SQL Server 2012
中不需要此字段。
使用AuditId
字段允许我们使用最小/最大聚合函数,并使用Partion By
作为查询的一部分,而不使用Order By
。
WITH CTE AS
(
SELECT AuditId, DocMasterId, PoNumber,
RN_ASC = ROW_NUMBER() OVER
(PARTITION BY DocMasterID ORDER BY AuditId ASC),
RN_DESC = ROW_NUMBER() OVER
(PARTITION BY DocMasterID ORDER BY AuditId DESC),
CNT = COUNT(*) OVER (PARTITION BY DocMasterID),
MIN(AuditId) OVER (PARTITION BY DocMasterId) AS F,
MAX(AuditId) OVER (PARTITION BY DocMasterId) AS L
FROM MyTable
WHERE (PONumber IS NOT NULL) AND (PONumber <> '') AND
(DocumentType = 'Purchase Order') and docmasterid > 0
)
然后,我们应用了几个inner join
来返回与AuditId关联的PONumber。
我们的审计表中返回的结果随后用于修复我们的实时表中的错误条目,因此确保FirstPO和LastPO确实在我们的审计表中的顺序正确是至关重要的。
SELECT DISTINCT CTE.DocMasterId, A.PONumber AS FirstPO, B.PONumber AS LastPO
FROM CTE
INNER JOIN MyTable A
ON CTE.F = A.AuditId
INNER JOIN MyTable B
ON CTE.L = B.AuditId
WHERE CNT >= 2 and a.PONumber <> B.PONumber
AND (RN_ASC = 1 OR RN_DESC = 1) AND (F <> L)
ORDER BY CTE.DocMasterId;
再次感谢所有人的帮助。非常感谢。