【发布时间】:2019-09-25 00:50:05
【问题描述】:
我有一个可以在 SQL Server 中正常运行的查询,但尝试使用 PYOBC 将其读入 DF 时出错。
我已将 SQL Server 中的确切查询复制并粘贴到我的 python 脚本中名为 query 的变量中(适用于所有其他查询)。
当我在 SQL Server 中运行查询时,这部分:
;WITH DeDupe AS (
-- Trace 105704 was received, returned to vendor, and re-received under same PO. DeDupe handles this
SELECT DISTINCT A.PurchaseOrderID, A.POLineNumber, D.TraceID
FROM #UniquePOs A
LEFT JOIN Trace.ReceivingReport B WITH (NOLOCK)
ON A.PurchaseOrderID = B.PurchaseOrderID AND A.POLineNumber = B.POLineNumber
LEFT JOIN Trace.EventInstance C WITH (NOLOCK)
ON B.EventInstanceID = C.InstanceID AND C.EventID = 'RCVD' -- Keep only receive events, not project transfers to avoid double-counting
LEFT JOIN Trace.Trace D
ON C.TraceID = D.TraceID
)
SELECT * INTO #DeDupe FROM DeDupe
SELECT * FROM #DeDupe; <---I take this part out when I try to run the query to get the second table.
;WITH TraceQtys AS (
-- Use this to solve Case 3 below
SELECT A.PurchaseOrderID, A.POLineNumber, SUM(B.Quantity) AS 'SumOfTraceQty'
FROM #DeDupe A
LEFT JOIN Trace.Trace B
ON A.TraceID = B.TraceID
GROUP BY A.PurchaseOrderID, A.POLineNumber
)
SELECT * INTO #TraceQtys FROM TraceQtys
SELECT * FROM #TraceQtys;
将这些作为结果返回:
PurchaseOrderID POLineNumber TraceID
-------------------------------------------------- ------------ -----------
007004 1 NULL
007004 1 41963
(2 rows affected)
Warning: Null value is eliminated by an aggregate or other SET operation.
(1 row affected)
PurchaseOrderID POLineNumber SumOfTraceQty
-------------------------------------------------- ------------ ---------------------------------------
007004 1 8.00000
在我的 Python 脚本中运行:
query = 'SET NOCOUNT ON; ' + query
query = query.replace('GO', '')
conn = pyodbc.connect('Driver={ODBC Driver 17 for SQL Server};'
'Server=SL-SQL;'
'Database=TRACE DB;'
'Trusted_Connection=yes;')
df = pd.read_sql(query, conn)
df.head()
上面对第一个表返回相同的结果,但对第二个表返回错误:
TypeError: 'NoneType' 对象不可迭代
这个类似的查询在 Python 中有效:
query = '''
SET NOCOUNT ON;
WITH Temp as (
SELECT TraceID, ClassID, SUM(Quantity) as Q
FROM Trace.Trace
GROUP BY TraceID, ClassID
)
SELECT * INTO #Temp FROM Temp
SELECT * FROM #Temp'''
如果我在 Python 查询中去掉这部分,它也会运行:
SUM(B.Quantity) AS 'SumOfTraceQty'
我有一段类似的代码可以成功运行(进一步):
WITH POQtys AS (
SELECT A.PurchaseOrderID, SUM(B.QtyVouched) AS POTotalQtyVouched
FROM #orders A
LEFT JOIN [MSS-ISD-DYN01].App.dbo.PurOrdDet B WITH (NOLOCK)
ON A.PurchaseOrderID = B.PONbr AND B.InvtID IN ('DIR-MATERIALS', 'ASSET-INVENTORY')
GROUP BY A.PurchaseOrderID
)
SELECT * INTO #POQtys FROM POQtys
【问题讨论】:
-
尝试
SUM(ISNULL(B.Quantity,0))在第二个CTE解决您的警告。 -
@JIKEN,谢谢!这对我有用。我猜在 Python 中你不能对空值求和,而在 SQL Server 中你可以?
-
@JIKEN,发现 NULL 值之间的计算是我问题的根源:stackoverflow.com/questions/58107175/…
-
所以,让我知道这个解决方案解决了您在进行任何聚合时是否解决了
NULL值的根本问题。 -
@JIKEN,谢谢。您的解决方案在这里对我有帮助。更深层次的问题是 pd.read_sql 和 read_sql_query 在 NULL 中读取为 0。我环顾四周,似乎没有办法阻止这种情况。
标签: sql sql-server python-3.x pandas pyodbc