我试图在不使用功能的情况下进行查询,因为它需要花费太多时间来提供结果。这是包含函数和结果的代码。
SELECT
LEFT(D2.D2_EMISSAO,6),
F2.F2_VEND1,
SUM((D2.D2_TOTAL-dbo.UCOMPRA(D2.D2_COD, D2.D2_EMISSAO)*D2.D2_QUANT)) AS LUCRO_LIQ
FROM SD2010 D2
INNER JOIN SF2010 F2
ON D2.D2_DOC = F2.F2_DOC AND D2.D2_SERIE = F2.F2_SERIE AND F2.D_E_L_E_T_= ''
WHERE
D2.D2_EMISSAO >= '20171201'
AND D2.D2_TES IN ('502','506')
GROUP BY
LEFT(D2.D2_EMISSAO,6),
F2.F2_VEND1
ORDER BY F2.F2_VEND1 DESC
这是功能:
ALTER FUNCTION dbo.UCOMPRA( @CODIGO VARCHAR(25), @DATE VARCHAR(8))
RETURNS float
BEGIN
DECLARE @UPRECO float;
SELECT TOP 1 @UPRECO = ROUND(D1.D1_CUSTO/D1.D1_QUANT,2)
FROM SD1010 D1
WHERE D1.D_E_L_E_T_ = ''
AND D1.D1_TES IN('015','202','205','206')
AND D1.D1_COD = @CODIGO
AND D1.D1_EMISSAO <= @DATE
ORDER BY D1.D1_EMISSAO DESC ;
RETURN ROUND(@UPRECO,2);
END;
GO
使用函数
的查询结果我试过这个:
SELECT D2.D2_EMISSAO,
D2.D2_DOC,
D2.D2_COD,
D2.D2_QUANT,
D2.D2_PRCVEN,
D2.D2_TOTAL,
ENTRADA.CUSTO,
((D2.D2_TOTAL/D2.D2_QUANT-ENTRADA.CUSTO)*D2.D2_QUANT) AS LUCRO_LIQ
FROM SD2010 D2
LEFT JOIN SD1010 D1 ON D2.D2_COD=D1.D1_COD
INNER JOIN (SELECT D1.D1_COD AS COD,D1.D1_TOTAL AS D1TOTAL,
D1.D1_TOTAL/D1.D1_QUANT AS CUSTO
FROM SD1010 D1
WHERE
D1.D1_EMISSAO <= '20171201'
AND D1.D1_TES IN ('015','202','205','206')
AND D1.D_E_L_E_T_='') ENTRADA
ON D2.D2_COD = ENTRADA.COD
WHERE D2.D2_COD = '000712S3B70340'
AND D1.D1_EMISSAO <= D2.D2_EMISSAO
AND D2.D2_TES IN ('502','506')
ORDER BY D2.D2_DOC DESC
Result of the code without You can see that the value from "lucro_liq" is diferent
答案 0 :(得分:2)
结果的差异是因为您在函数中使用Order by
,但在sub-select
中没有order by
。通过内部子选择添加顺序也没有任何意义。
我希望inline table valued
功能优于scalar
功能
DROP FUNCTION dbo.Ucompra
go
CREATE FUNCTION dbo.Ucompra(@CODIGO VARCHAR(25),
@DATE VARCHAR(8))
RETURNS TABLE
RETURN
(SELECT TOP 1 UPRECO = Round(D1.D1_CUSTO / D1.D1_QUANT, 2)
FROM SD1010 D1
WHERE D1.D_E_L_E_T_ = ''
AND D1.D1_TES IN( '015', '202', '205', '206' )
AND D1.D1_COD = @CODIGO
AND D1.D1_EMISSAO <= @DATE
ORDER BY D1.D1_EMISSAO DESC)
GO
SELECT LEFT(D2.D2_EMISSAO, 6),
F2.F2_VEND1,
Sum(( D2.D2_TOTAL - oa.UPRECO * D2.D2_QUANT )) AS LUCRO_LIQ
FROM SD2010 D2
INNER JOIN SF2010 F2
ON D2.D2_DOC = F2.F2_DOC
AND D2.D2_SERIE = F2.F2_SERIE
AND F2.D_E_L_E_T_ = ''
OUTER apply dbo.Ucompra(D2.D2_COD, D2.D2_EMISSAO) oa
WHERE D2.D2_EMISSAO >= '20171201'
AND D2.D2_TES IN ( '502', '506' )
GROUP BY LEFT(D2.D2_EMISSAO, 6),
F2.F2_VEND1
ORDER BY F2.F2_VEND1 DESC