MySQL在MSSQL中等效于分配变量并使用它

时间:2018-06-15 23:13:37

标签: mysql sql sql-server

我试着找到答案,但也许我对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。

3 个答案:

答案 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 ;