简体   繁体   中英

Usage of result from one column in computation in different column in MSSQL Server

I'm trying to use the result from one column in computation in later columns in MS SQL Server.

Below is my SQL code:

SELECT 
(SELECT 'EURUSD' AS a) AS symbol_name,
(SELECT TOP 1  ROUND(p.BidLast,5) FROM mt5_prices p WHERE p.Symbol LIKE 'EURUSD%') AS Bid,

(SELECT SUM(m.Volume) 
FROM mt5_positions m
WHERE m.Symbol LIKE 'EURUSD%' AND m.Login IN (SELECT u.Login FROM mt5_users u WHERE u."Group" LIKE 'real%') AND m."Action" = 0) AS TotalBuy,

(SELECT CASE 
WHEN 'EURUSD' LIKE 'USOIL%' OR 'EURUSD' LIKE 'UKOIL%' OR 'EURUSD' LIKE 'Bund%' THEN ROUND(TotalBuy/10*Bid,2) 
WHEN 'EURUSD' LIKE 'NGAS%' OR 'EURUSD' LIKE 'Copper%' THEN ROUND(TotalBuy/1*Bid,2)
ELSE ROUND(TotalBuy/100*Bid,2) END) AS ExpositionBuyLots

Of course, the error returned is:

SQL Error (207): Invalid column name 'TotalBuy'
Invalid column name 'Bid'.

My question is: How can I use the already (or, so to speak "on-the-fly") computed result from columns TotalBuy and Bid ? I read about computed columns, but unfortunately, modification of database is not possible.

MS SQL Server 2012 version.

EDIT: The above functionality is available in MySQL, I hope in MS SQL this can be achieved too. If someone is interested about the solution (I chose @Damien because it is closest one to the original MySQL query (yes, it is query, rewritten from MySQL to MSSQL), ie require only small SQL modification):

SELECT * FROM    
(SELECT 'EURUSD' AS symbol_name) symbol_name

CROSS apply

(SELECT TOP 1  ROUND(p.AskLast,5) AS Ask FROM mt5_prices p WHERE p.Symbol LIKE 'EURUSD%') Ask

CROSS apply

(SELECT TOP 1  ROUND(p.BidLast,5) AS Bid FROM mt5_prices p WHERE p.Symbol LIKE 'EURUSD%') Bid

CROSS apply

(SELECT SUM(m.Volume) AS TotalBuy
FROM mt5_positions m
WHERE m.Symbol LIKE 'EURUSD%' AND m.Login IN (SELECT u.Login FROM mt5_users u WHERE u."Group" LIKE 'real%') AND m."Action" = 0) TotalBuy

CROSS apply

(SELECT SUM(m.Volume) AS TotalSell
FROM mt5_positions m
WHERE m.Symbol LIKE 'EURUSD%' AND m.Login IN (SELECT u.Login FROM mt5_users u WHERE u."Group" LIKE 'real%') AND m."Action" = 1) TotalSell

CROSS apply

(SELECT (CASE 
WHEN 'EURUSD' LIKE 'USOIL%' OR 'EURUSD' LIKE 'UKOIL%' OR 'EURUSD' LIKE 'Bund%' THEN ROUND(TotalBuy/10*Bid,2) 
WHEN 'EURUSD' LIKE 'NGAS%' OR 'EURUSD' LIKE 'Copper%' THEN ROUND(TotalBuy/1*Bid,2)
ELSE ROUND(TotalBuy/100*Bid,2) END) AS ExpositionBuyLots) ExpositionBuyLots

You can use another sub query block to achieve this:

SELECT (
        CASE 
            WHEN 'EURUSD' LIKE 'USOIL%'
                OR 'EURUSD' LIKE 'UKOIL%'
                OR 'EURUSD' LIKE 'Bund%'
                THEN ROUND(TotalBuy / 10 * Bid, 2)
            WHEN 'EURUSD' LIKE 'NGAS%'
                OR 'EURUSD' LIKE 'Copper%'
                THEN ROUND(TotalBuy / 1 * Bid, 2)
            ELSE ROUND(TotalBuy / 100 * Bid, 2)
            END
        ) AS ExpositionBuyLots, *
FROM (
    SELECT ( SELECT 'EURUSD' AS a ) AS symbol_name
          ,( SELECT TOP 1 ROUND(p.BidLast, 5)
            FROM mt5_prices p
            WHERE p.Symbol LIKE 'EURUSD%'
            ) AS Bid
          ,( SELECT SUM(m.Volume)
            FROM mt5_positions m
            WHERE m.Symbol LIKE 'EURUSD%'
                AND m.LOGIN IN (
                    SELECT u.LOGIN
                    FROM mt5_users u
                    WHERE u."Group" LIKE 'real%'
                    )
                AND m."Action" = 0
            ) AS TotalBuy
    ) AS R

You can use cross apply (or subqueries) to introduce additional select clauses. Each select clause is computed "as if" all expressions are computed in parallel - that's why there cannot be dependencies between the expressions within a single select clause.

Eg:

select
    *
from
    sys.objects
        cross apply
    (select object_id + 10 as mega_object_id) u
        cross apply
    (select mega_object_id / 30 as little_object_id) w

You should use APPLY operator. You can use values from YourTable in APPLY

SELECT 
    ExpositionBuyLots = CASE 
        WHEN 'EURUSD' LIKE 'USOIL%' OR 'EURUSD' LIKE 'UKOIL%' OR 'EURUSD' LIKE 'Bund%' THEN ROUND(ComputedValues.TotalBuy/10*ComputedValues.Bid,2) 
        WHEN 'EURUSD' LIKE 'NGAS%' OR 'EURUSD' LIKE 'Copper%' THEN ROUND(ComputedValues.TotalBuy/1*ComputedValues.Bid,2)
        ELSE ROUND(ComputedValues.TotalBuy/100 * ComputedValues.Bid,2) END
FROM YourTable
OUTER APPLY (
    SELECT
        symbol_name = 'EURUSD',
        Bid         = (SELECT TOP 1  ROUND(p.BidLast,5) FROM mt5_prices p WHERE p.Symbol LIKE 'EURUSD%') ,
        TotalBuy    = (SELECT SUM(m.Volume) 
                          FROM mt5_positions m
                          WHERE m.Symbol LIKE 'EURUSD%' AND m.Login IN (SELECT u.Login FROM mt5_users u WHERE u."Group" LIKE 'real%') AND m."Action" = 0
                      ) 
) ComputedValues

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM