我试着找到答案,但也许我对MSSQL太新了,我来自MySQL,所以这是我的问题超级简化直截了当: 想象一下,我们有一个表“事物”
Thingie | Value --------+------- Thing1 | 10 Thing1 | 15 Thing1 | 16
在MySQL中,我可以在查询中执行以下操作:
SET @halfvalue := 0; SELECT Thingie, Value, (@halfvalue := Value / 2) AS HalfValue, (@halfvalue / 2) AS HalfOfHalf FROM Things
哪会返回
Thingie | Value | HalfValue | HalfofHalf --------+-------+-----------+------------ Thing1 | 10 | 5.00 | 2.50 Thing1 | 15 | 7.50 | 3.75 Thing1 | 16 | 8.00 | 4.00
看起来很简单,实际的那个有点复杂。 我的问题是,在MSSQL中,我不能分配,并且在同一个SELECT上使用变量。在这个简单的层面上,我找不到任何类似于此功能的东西。
任何解决方案?
编辑,这是包含所有那些令人讨厌的操作的选择:
SELECT
fvh.DocEntry,
MAX( fvs.SeriesName ) AS "Serie",
MAX( fvh.DocNum - 1000000 ) AS "Número",
MAX( fvh.DocDate ) AS "Fecha",
MAX( fvh.U_FacNit ) AS "NIT",
MAX( fvh.U_FacNom ) AS "Nombre",
MAX( IIF( ISNULL( fvh.Address, '' ) = '', fvh.Address2, fvh.Address ) ) AS "Dirección",
SUM( fvd.GTotal - ISNULL( ncd.GTotal, 0 ) ) AS "Total",
IIF( MAX( fvh.CANCELED ) = 'Y' OR ( SUM( fvd.GTotal - ISNULL( ncd.GTotal, 0 ) ) = 0 ),
'Anulada',
IIF( SUM( fvd.GTotal ) > SUM( ISNULL( ncd.GTotal, 0 ) ) AND ( SUM( ISNULL( ncd.GTotal, 0 ) ) > 0 ),
'Devuelta',
'Emitida' )
) AS "Estado",
ROUND( ( ( SUM( fvd.GTotal - ISNULL( ncd.GTotal, 0 ) ) / 1.12 ) * 0.12 ), 4 ) AS "IVA",
ROUND( SUM( IIF( fvd.U_TipoA = 'BB',
( fvd.GTotal - ISNULL( ncd.GTotal, 0 ) ) - ( ( ( fvd.GTotal - ISNULL( ncd.GTotal, 0 ) ) / 1.12 ) * 0.12 ),
0 ) ), 4) AS "Bien",
ROUND( SUM( IIF( fvd.U_TipoA = 'S',
( fvd.GTotal - ISNULL( ncd.GTotal, 0 ) ) - ( ( ( fvd.GTotal - ISNULL( ncd.GTotal, 0 ) ) / 1.12 ) * 0.12 ),
0 ) ), 4) AS "Servicio",
ROUND( SUM( IIF( fvd.U_TipoA = 'N',
( fvd.GTotal - ISNULL( ncd.GTotal, 0 ) ) - ( ( ( fvd.GTotal - ISNULL( ncd.GTotal, 0 ) ) / 1.12 ) * 0.12 ),
0 ) ), 4) AS "No Aplica",
COUNT(fvd.LineNum) AS "Lineas", SUM(fvd.GTotal) AS "FCTotal",
SUM(ISNULL( ncd.GTotal, 0 )) AS "NCTotal"
/* Facturas */
FROM OINV AS fvh
LEFT JOIN NNM1 AS fvs ON fvs.Series = fvh.Series
LEFT JOIN INV1 as fvd ON fvd.DocEntry = fvh.DocEntry
/* Notas de Credito */
LEFT JOIN RIN1 AS ncd ON ncd.BaseEntry = fvh.DocEntry AND ncd.LineNum = fvd.LineNum
WHERE fvh.DocDate BETWEEN ? AND ? /*AND fvh.DocEntry = 1108*/
GROUP BY fvh.DocEntry
谢谢大家的时间。我将拆除我的查询并重新考虑你的所有输入。 Gracias,totales。
答案 0 :(得分:1)
您认为您可以在MySQL中执行此操作:
SET @halfvalue := 0;
SELECT Thingie, Value,
(@halfvalue := Value / 2) AS HalfValue,
(@halfvalue / 2) AS HalfOfHalf
FROM Things;
但你错了。为什么? MySQL - 与所有其他数据库一样 - 不保证SELECT
中表达式的评估顺序。 documentation甚至对此发出警告:
在下面的语句中,您可能会认为MySQL将首先评估@a,然后再进行一次分配:
SELECT @a, @a:=@a+1, ...;
但是,涉及用户变量的表达式的评估顺序是未定义的。
在两个数据库中,您都可以使用子查询。在最新版本的MySQL(以及几乎任何其他数据库)中,您还可以使用CTE:
SELECT Thingie, Value, HalfValue,
(HalfValue / 2) AS HalfOfHalf
FROM (SELECT t.*, (Value / 2) AS HalfValue
FROM Things t
) t;
答案 1 :(得分:0)
答案很简单:你不能在MSSQL中这样做,因为当你尝试它时你会得到:
Msg 141,Level 15,State 1,Line 3 为变量赋值的SELECT语句不能与数据检索操作结合使用。
你最有可能经历过。
最简单的解决方法是:
SELECT Thingie, Value, Value/2, Value/4 from Things
其他方法:
select Thingie, Value, HalfValue, HalfValue / 2 from (
SELECT Thingie, Value, Value / 2 HalfValue from Things
) a
答案 2 :(得分:-2)
不,这在SQL中不起作用。在查询完成之前,不会设置参数值。您可以分两步完成:
DECLARE @halfvalue FLOAT = 0;
SELECT @halfvalue = ([Value] / 2)
FROM Things ;
SELECT Thingie
, [Value]
, HalfValue = [Value]/2
, HalfAgainValue = @halfvalue / 2
FROM Things ;