I use SQL Server, and I created view and added new column which contain mathematical equation
Let's say I have this:
create view
as
select
a.date, a.sale, a.buy,
profit = a.sale - a.buy,
profit_prs = (a.sale - a.buy) / a.sale
from
tableA a
In line 5 how can I use [profit]
column in [profit_prs]
expression
to be like this:
profit_prs = profit / a.sale
CodePudding user response:
- First-off: you need to address the divide-by-zero error that's looming in your query...
- Change
(a.sale - a.buy) / a.sale
to( a.sale - a.buy ) / NULLIF( a.sale, 0.0 )
- that way you'll get aNULL
inprofit_prs
instead of your query aborting entirely.- Moving on....
- Change
- ISO/ANSI SQL does not allow a
SELECT
projection to refer to new column expressions in the same query "level" (i.e. within the sameSELECT
clause of the same derived-table or CTE or other table expression).- Some RDBMS extend SQL to allow it, such as MySQL.
- Instead, uou will need to use a new derived-table or a CTE to add a new "logical step" to the query which will
SELECT
your base-table'sdate
,sale
, andbuy
columns, and define the newprofit
column.- ...and the next (outer-er)
SELECT
can then define theprofit_prs
column based on the previous step'sprofit
column. - However, when you do this, the end-result is very verbose and probably harder to maintain:
- ...and the next (outer-er)
This is what the VIEW
looks like when using a new CTE to represent the inner step:
CREATE VIEW dbo.MyView AS
WITH q1 AS (
SELECT
a.date,
a.sale,
a.buy,
profit = ( a.sale - a.buy )
FROM
dbo.TableA AS a
)
SELECT
q1.date,
q1.sale,
q1.buy,
q1.profit,
profit_prs = q1.profit / NULLIF( a.sale, 0.0 )
FROM
q1;
Whereas if you don't mind the repetition of ( a.sale - a.buy )
you still end-up with a much shorter query:
CREATE VIEW dbo.MyView AS
SELECT
a.date,
a.sale,
a.buy,
profit = ( a.sale - a.buy ),
profit_prs = ( a.sale - a.buy ) / NULLIF( a.sale, 0.0 )
FROM
dbo.TableA AS a;
CodePudding user response:
That’s a good spot to use cross apply
; you can move the calculation to to an inline table of values, then reuse it as you wish in the select
clause:
create view myview as
select a.date, a.sale, a.buy,
x.profit,
x.profit / nullif(a.sale, 0) profit_prs
from tableA a
cross apply ( values (a.sale - a.buy) ) x(profit)