SQL Computed Column If Statement - sql-server

This is not working. Still getting division by zero error. Any ideas?
case when [games]=NULL then (0)
when [games]=(0) then (0)
else CONVERT([decimal](18,2),CONVERT([float],[goalsAG],(0))/CONVERT([float],[games],(0)),(0)) end

You can never use = with NULL, use IS NULL.
And simplified further:
(case when isnull([games], 0) = 0 then (0) else CONVERT(decimal,CONVERT([float],[goalsAG],(0))/CONVERT([float],[games],(0)),(0)) end)

Related

Convert Access SQL IIF to T-SQL CASE statement

I have someone else's Access query that I need to convert to T-SQL. I have it mostly done. These next two lines are my issue. This is the Access SQL:
...
, [MATERIALVALUE]/1000 AS COSTOURS
...
, IIf([ALLJOBS].[SALESID]="SUI",[COSTOURS]=0,IIf([PRICE]=-1,[COSTOURS]=0,[COSTOURS])) AS COST0
...
The first line COSTOURS is simple enough. It is just
...
,MATERIALVALUES/1000 COSTOURS
...
What I am having problems with is the setting of COSTOURS later in the same SELECT statement's CASE statement as well as what is COST0 getting set to?
My T-SQL case statement is this:
,CASE AllJobs.SALESID
WHEN 'SUI' THEN COSTOURS = 0
ELSE CASE ESSDBtRels.PRICE
WHEN -1 THEN COSTOURS = 0
ELSE ESSDBtRels.MATERIALVALUE/1000
END
END COST0
Which doesn't work obviously. How do I set a previously set column with new results based on a subsequent CASE statement's true attributes. And what does COST0 get set to in the case of a TRUE and a FALSE, TRUE occasion? A FALSE, FALSE will set COST0 to COSTOURS.
Thanks #forpas, since MATERIALVALUE has no bearing I will go with the following SQL:
CASE AllJobs.SALESID
WHEN 'SUI' THEN 0
ELSE CASE ESSDBtRels.PRICE
WHEN 1 THEN 0
ELSE ESSDBtRels.MATERIALVALUE/1000
END
END COST0
In MS Access a Boolean expression like [COSTOURS]=0 is evaluated as -1 for TRUE or 0 for FALSE.
So to get the same results you should use a CASE statement in the place of these expressions:
CASE AllJobs.SALESID
WHEN 'SUI' THEN CASE ESSDBtRels.[MATERIALVALUE] WHEN 0 THEN -1 ELSE 0 END
ELSE CASE ESSDBtRels.PRICE
WHEN -1 THEN CASE ESSDBtRels.[MATERIALVALUE] WHEN 0 THEN -1 ELSE 0 END
ELSE ESSDBtRels.MATERIALVALUE/1000
END
END COST0
or with IIF():
IIF(
[ALLJOBS].[SALESID]='SUI',
IIF(ESSDBtRels.MATERIALVALUE=0, -1, 0),
IIf(
[PRICE]=-1,
IIF(ESSDBtRels.MATERIALVALUE=0, -1, 0),
ESSDBtRels.MATERIALVALUE/1000
)
) AS COST0

IIF to Case statement

I have the below code in Access which I'm migrating to SQL Server,
IIf([code] Is Not Null,IIf([code]<>'ABC',
IIf([length] Is Null,1,IIf([Length]=0,1,
IIf([width] Is Null,1,IIf([Width]=0,1,
IIf([height] Is Null,1,IIf([Height]=0,1,
0))))))))
I believe it checks for code not null and not equal to 'ABC' then length should be null or 0 then it assigns a value 1 of the condition fails then it is 0. I need a little help with writing it with case.
Literal translating:
CASE WHEN [code] Is Not Null
THEN
CASE WHEN [code]<>'ABC'
THEN
CASE WHEN [length] Is Null
THEN 1
ELSE
CASE WHEN [Length]=0
THEN 1
ELSE
CASE WHEN [width] Is Null
THEN 1
ELSE
CASE WHEN [Width]=0
THEN 1
ELSE
CASE WHEN [height] Is Null
THEN 1
ELSE
CASE WHEN [Height]=0
THEN 1
ELSE 0
END
END
END
END
END
END
END
END
Simplified in :
CASE WHEN ISNULL([code], 'ABC') <>'ABC' AND
(ISNULL([length], 0) = 0 OR
ISNULL([width], 0) = 0 OR
ISNULL([height], 0) = 0)
THEN 1
ELSE 0
END
IIf in JET SQL translates to CASE WHEN in SQL Server as follows:
IIf(condition, whenTrue, whenFalse)
translates directly to
CASE WHEN condition THEN whenTrue ELSE whenFalse END
For nested expressions
IIf(condition1, whenTrue1, IIf(condition2, whenTrue2, whenFalse))
you can either translate them directly:
CASE WHEN condition1
THEN whenTrue1
ELSE CASE WHEN condition2
THEN whenTrue2
ELSE whenFalse
END
END
or use the fact that CASE allows you to specify multiple WHEN conditions:
CASE WHEN condition1 THEN whenTrue1
WHEN condition2 THEN whenTrue2
ELSE whenFalse
END
With this knowledge, translating your statement should be easy and is left as an exercise to the reader (I don't want to spoil the fun).

returning a bit type in a stored procedure

I have a stored procedure in which I am validating some columns to return a value of 1 or 0.
The stored proc code block is:
, CASE WHEN
(PolicyStartMileage < LossMileage)
AND (PolicyStartDate <= LossDate)
AND (Certified = 0)
THEN '1'
ELSE '0'
END
AS Certifiable
My question is, how do I return '1' or '0' as a bit type?
In my codebehind, I am using:
Boolean.Parse(item.GetDataKeyValue("Certifiable").ToString());
in order to read the value (true or false).
If you want the data to be a true BIT data type you need to do a cast, otherwise it will default to numeric.
CASE WHEN
(PolicyStartMileage < LossMileage)
AND (PolicyStartDate <= LossDate)
AND (Certified = 0)
THEN CAST(1 AS BIT)
ELSE CAST(0 AS BIT)
END
AS Certifiable
If you do the cast, you can call the GetBoolean() method from the data reader directly avoiding the parse
, CASE WHEN
(PolicyStartMileage < LossMileage)
AND (PolicyStartDate <= LossDate)
AND (Certified = 0)
THEN 1
ELSE 0
END
AS Certifiable
when you use Quotes around 1 or 0 it treats it as a string not
integer.
Try to remove the quotes '' around 1 and 0 so that it behaves as integers rather than string. like this:
, CASE WHEN
(PolicyStartMileage < LossMileage)
AND (PolicyStartDate <= LossDate)
AND (Certified = 0)
THEN 1
ELSE 0
END
AS Certifiable

'an expression of non boolean type specified' in CASE WHEN

Given this T-SQL code:
SELECT CASE
WHEN ( Cast (CASE
WHEN Isnull(bpe.new, 0) = 0
AND Isnull(bpe.regular, 0) = 0
AND Isnull(bpe.bargain, 0) = 0 THEN 0
ELSE 1
END AS BIT)
AND #siteID IS NULL
OR bpe.siteid = #siteID ) THEN 1
ELSE 0
END AS SiteHasBrandException
FROM brandpromoexceptions AS bpe
I get the error message:
an expression of non boolean type specified in the context where a condition is expected TSQL
Why is that?
If you mean zero as "false" for that first bit, the query should be equivalent to:
SELECT CASE WHEN
NOT ( ISNULL(bpe.new, 0) = 0
AND Isnull(bpe.regular, 0) = 0
AND Isnull(bpe.bargain, 0) = 0 )
AND ( #siteID IS NULL
OR bpe.siteid = #siteID )
THEN 1
ELSE 0
END AS SiteHasBrandException
FROM brandpromoexceptions AS bpe
You may need to be careful with that "OR" clause, or add parentheses for clarification. I guessed here.
You are passing your first CASE statement a call to CAST rather than a conditional. The error message pretty much spells it out.
I'm not sure exactly what you are trying to do, but you seem to understand that you need to pass a boolean to the CASE WHEN based on your subsequent use of CASE so hopefully this helps.
this is a shot in the dark by try changing your code to this:
SELECT CASE
WHEN ( Cast (CASE
WHEN Isnull(bpe.new, 0) = 0
AND Isnull(bpe.regular, 0) = 0
AND Isnull(bpe.bargain, 0) = 0 THEN 0
ELSE 1
END AS BIT) = 1
AND #siteID IS NULL
OR bpe.siteid = #siteID ) THEN 1
ELSE 0
END AS SiteHasBrandException
FROM brandpromoexceptions AS bpe

How to get all values including null in a SQL Server case statement?

I have a big stored procedure, and basically I want to select all values (including null) if my variable #DimBrowserId is set to 0. I am using a case statement, however this is only catching values that actually have something and ignoring the NULL valued fields. Because I am using the = clause in the WHERE I cannot do IS NULL. I do not want to have to write 2 IF statements because the stored procedure would then be enormous, so I want to know how to get null values as well. Here is my code:
SELECT
DATEPART(yy, DATEADD(mi, #Mdelta, d.DimDateValue)),
DisableCount = COUNT(*)
FROM
dbo.FactDisable AS f
JOIN
dbo.DimDate AS d ON f.DimDateId = d.DimDateId
JOIN
dbo.DimDevice AS v ON f.DimDeviceId = v.DimDeviceId
WHERE
d.DimDateValue >= #StartDateGMT
AND d.DimDateValue <= #EndDateGMT
AND f.IsTest = #IncludeTest
AND f.DimProductId = #DimProductId
AND v.DimBrowserId = CASE
WHEN #DimBrowserId = 0 THEN v.DimBrowserId
ELSE #DimBrowserId
END
GROUP BY
DATEPART(yy, DATEADD(mi, #Mdelta, d.DimDateValue))
The code is near the CASE clause.
Thanks
Change that line to be
AND (#DimBrowserID = 0 OR #DimBrowserID = v.DimBrowserId)
If #DimBroserID is 0 then no filtering will be applied for this line.
Use ISNULL:
SELECT DATEPART(yy,DATEADD(mi,#Mdelta,d.DimDateValue)),
DisableCount=COUNT(*)
FROM dbo.FactDisable AS f
JOIN dbo.DimDate AS d ON f.DimDateId = d.DimDateId
JOIN dbo.DimDevice AS v ON f.DimDeviceId = v.DimDeviceId
WHERE d.DimDateValue >= #StartDateGMT AND d.DimDateValue <= #EndDateGMT
AND f.IsTest = #IncludeTest AND f.DimProductId = #DimProductId
AND v.DimBrowserId = CASE WHEN ISNULL(#DimBrowserId,0) = 0 THEN v.DimBrowserId ELSE #DimBrowserId END
GROUP BY DATEPART(yy,DATEADD(mi,#Mdelta,d.DimDateValue))
CASE WHEN COALESCE(#MightBeNull, 0) = 0 THEN ZeroResult ...
will be treated as zero if #MightBeNull is null, and whatever #MightBeNull is if it's not null.
Assuming null means any browser, a better data model for this scenario might be to set an ID that identifies any browser, instead of setting it to null.
You probably know what you are running into is NULL does not equal NULL in a comparison.
Assuming you don't have control of the data model to fix that, one option would be to coalesce your NULL values to an unused id.
The resulting WHERE clause would look like this, assuming -1 is the unused value you choose.
AND COALESCE(v.DimBrowserId, -1) = CASE WHEN #DimBrowserId = 0 THEN COALESCE(v.DimBrowserId, -1) ELSE #DimBrowserId END

Resources