Iff condition Access to SQL syntax - sql-server

I have an access query that I have recreate in SQL.
Access:
SELECT Columns ,
IIf([Col1]="X",IIf([COL2]<>"XXXX",1,0)) AS NEWCOL1,
IIf([COL2] Not In ("HHH","GGG"),1,0) AS [NEWCOL2],
IIf(([NEWCOL1]=1) Or ([NEWCOL2]=1),1,0) AS NEWCOL3
FROM [TABLE]
WHERE ((([TABLE].COL2)<>"XXXX")) OR ((([TABLE].COL2)<>"HHH" And ([TABLE].COL2)<>"GGG"));
In SQL :
SELECT Columns ,
"NEWCOL1" =
CASE WHEN ([COL1]='X' AND COL2<> 'XXXX') THEN 1
ELSE 0
END,
"NEWCOL2" =
CASE WHEN COL2 NOT IN ('HHH','GGG') THEN 1
ELSE 0
END ,
IIf(([NEWCOL1]=1) Or ([NEWCOL2]=1),1,0) AS NEWCOL3
FROM [TABLE]
WHERE ((([TABLE].COL2)<>'XXXX')) OR ((([TABLE].COL2)<>'HHH' And ([TABLE].COL2)<>'GGG'));
IIf(([NEWCOL1]=1) Or ([NEWCOL2]=1),1,0) AS NEWCOL3
When I use the Newcol1 and newcol2 it throws an error invalid column how could use them maybe in a nested case or iif statement

If you're in SQL 2012, where IIF() is valid, then it looks like the problem is that you don't have an ELSE value for the first outer case:
IIf([Col1]='X',IIf([COL2]<>'XXXX',1,0){,NEED SOME ELSE VALUE HERE}) AS NEWCOL1,
I don't know why this would work in Access. I guess Access must be more "dummy proof" than SQL Server.
To replace your original first IIF with a CASE, you would do this:
CASE WHEN [Col1]='X' THEN
CASE WHEN [COL2]<>'XXXX' THEN 1 ELSE 0 END
END
By not supplying an ELSE for the first condition, if [Col1] does not equal 'X', the statement will return NULL without raising an error.
To handle your most recent request with a CTE, you could do as below:
WITH cte AS (
SELECT
Columns,
CASE WHEN ([COL1]='X' AND COL2<> 'XXXX') THEN 1 ELSE 0 END AS NEWCOL1,
CASE WHEN COL2 NOT IN ('HHH','GGG') THEN 1 ELSE 0 END AS NEWCOL2
FROM [TABLE]
WHERE ((([TABLE].COL2)<>'XXXX')) OR ((([TABLE].COL2)<>'HHH' And ([TABLE].COL2)<>'GGG'))
)
SELECT *, IIf(([NEWCOL1]=1) Or ([NEWCOL2]=1),1,0) AS NEWCOL3
FROM cte;

Related

Set all column values based on condition existing in one row using Snowflake

Working on a view in Snowflake and based certain criteria I want to set the Pass/Fail column for all rows to "Pass" if a certain output is reached. Example (below)for a give Item number/ Plant combination, where the condition is met for one row, I would like to set all rows to "Pass"
Here is my case statement as is: I'm Having trouble getting this scenario to "Pass" for all rows
case
when
((case
when 'PIRStatus' is null
then 'PIR-Missing'
else 'PIR-Exists'
end)='PIR-Exists'
and "FixedVendor" = 'X'
and (case
when "SLStatus" = 'SL-Exists'
then 1
else 2
end) = 1)
then 'Pass'
else 'Fail'
end as "Pass/Fail"
PIRStatus Vendor BlockedVendor FixedVendor SLStatus Pass/Fail
PIR-Exists 12547 X SL-Exists Pass
PIR-Exists 85996 SL-Missing Fail
PIR-Exists 54788 SL-Missing Fail
This is based on a given Item/ Plant combination, as long as any row says pass then I want the other rows to Pass as well
You probably want to use a correlated subquery, which I find is best written with a CTE like this:
WITH CTE_CONDITION AS (
SELECT
id,
case when (
(
case when 'PIRStatus' is null then 'PIR-Missing' else 'PIR-Exists' end
)= 'PIR-Exists'
and "FixedVendor" = 'X'
and (
case when "SLStatus" = 'SL-Exists' then 1 else 2 end
) = 1
) then 'Pass' else 'Fail' end as "Pass/Fail"
FROM
table
)
SELECT
* ,
CASE WHEN EXISTS (SELECT 1 FROM CTE_CONDITION WHERE "Pass/Fail" = 'Pass' AND table.id = CTE_CONDITION.id)
THEN 'This ID Passes At Least Somewhere'
ELSE 'This ID never passes'
END as DOES_THIS_EVER_PASS
FROM table
The thing to remember using EXISTS is that the SELECT portion doesn't really matter (thus, SELECT 1) but it is the WHERE clause that connects the table itself to CTE_CONDITION.
You might even clean this up by creating CTE_PASS and CTE_FAIL and putting conditions in the WHERE clauses, to compartmentalize the logic and avoid that messy CASE statement.
Thus, you could accomplish the same thing with something like:
WITH CTE_PASS AS (
SELECT id
FROM table
WHERE {conditions that mean a pass}
)
SELECT
* ,
CASE WHEN EXISTS (SELECT 1 FROM CTE_PASS WHERE table.id = CTE_CONDITION.id)
THEN 'This ID Passes At Least Somewhere'
ELSE 'This ID never passes'
END as DOES_THIS_EVER_PASS
FROM table

Case statement with end = 1 in T/SQL query

I'm hoping somebody can explain the below query to me as I'm not familiar with the syntax:
#[user1] int,
#[user2] varchar(10)
delete
from [table name]
where [id] in (select [id]
from [a diff table name]
where [user1] = #[user1])
and (case
when [user2] = 'some string' then 1
when [table field] = #user2 then 1
else 0
end) = 1
and [other field] = 0
and [other field] = 0
and [other field]= 0
Firstly, I've obviously changed all variable/table names. Apologies if anything isn't clear. I get that the first part is a delete statement where it uses an in statement. That's fine. I also get the last part, with the multiple AND statements adding conditions to the WHERE clause.
It's the case statement I'm struggling with. I've two questions.
What is the else 0 for? Is that attached to the when clause above it, so that if [table field] doesn't = the user2 variable passed in it is set to 0?
What is the end = 1? I've tried googling but haven't found any examples of this form before.
ELSE 0 means that the CASE statement will return 0 if neither of the WHEN statements are matched.
End = 1 is easier to understand if you think of it as
WHERE (CASE .... END) = 1
Your CASE stmt will return either 1 or 0 depends on data in that column.
IF it return 1 then 1=1 and other conditions which specified below will also happen.
IF it return 0 then 0=1 , Remaining conditions won't be considered.

Aggregate Function Error on an Expression

What could be wrong with this query:
SELECT
SUM(CASE
WHEN (SELECT TOP 1 ISNULL(StartDate,'01-01-1900')
FROM TestingTable
ORDER BY StartDate Asc) <> '01-01-1900' THEN 1 ELSE 0 END) AS Testingvalue.
The get the error:
Cannot perform an aggregate function on an expression containing an aggregate or a subquery.
As koppinjo stated what your current (broken) query is doing is checking if you have a NULL-value (or StartDate = '01-01-1900') in your table, return either a 1 or a 0 depending on which, and then attempting to SUM that single value.
There are 2 different logical things you want.
Either getting the amount of rows that has a StartDate or checking if any row is missing StartDate.
SELECT --Checking if there is a NULL-value in table
(
CASE WHEN
(SELECT TOP 1 ISNULL(StartDate,'01-01-1900')
FROM TestingTable
ORDER BY StartDate Asc) <> '01-01-1900' THEN 1
ELSE 0
END
) AS TestingValue
SELECT SUM(TestingValue) TestingValue --Give the count of how many non-NULLs there is
FROM
(
SELECT
CASE WHEN
ISNULL(StartDate,'01-01-1900') <> '01-01-1900' THEN 1
ELSE 0
END AS TestingValue
FROM TestingTable
) T
Here is a SQL Fiddle showing both outputs side by side.
Hard to say, but you probably want something like this:
SELECT
SUM(TestingValue)
FROM
(SELECT
CASE
WHEN ISNULL(StartDate,'01-01-1900') <> '01-01-1900'
THEN 1
ELSE 0
END AS TestingValue
FROM TestingTable) t
As your original query is written now, your subquery will return 1 value overall, so your sum would be 1 or 0 always, not to mention it is illegal. To get around that, this SQL will apply the case statement to every row in the TestingTable and insert the result into a derived table (t), then the 'outer' select will sum the results. Hope this helps!

sum in case vs case in sum in SQL server ?

Is there any difference between writing :
select
...,
mySum= CASE
WHEN i IS NULL THEN 0 ELSE SUM(i)
END
...
vs
select
...,
mySum= SUM( CASE WHEN i IS NULL THEN 0 ELSE i
END
)
...
Or is it just 100% the same ( logically and traps...)?
On my test data, I get the same results returned, and near identical execution plans:
All the same costs, just two operations reversed.
I think logically there is no difference. But I think you don't need to check for null in this case as aggregate functions ignore nulls
BTW, You can simplify case with a isnull as follows. (Edit: mistakenly added sum(isnull(i,0)) changed to Isnull(sum(i),0))
select Col1, Isnull(sum(i),0) as mySum
from yourTable
group by Col1

SQL Server INLINE IF ELSE

In my table I got a column whose value is whether 0 or 1. If that column is 0 I output the value as 'no'; if 1 I should output as 'yes' for all rows. How can I do this only using SQL statement. Thanks
I understand that this question (which shows up at the top of google results for "sql server inline if") is 2 years old, but with SQL Server 2012, the answers are somewhat outdated. It also appears to be a duplicate of SQL inline if statement type question, but that question (being an even older one), doesn't have an up to date answer either.
In SQL Server 2012 you can use the IIF function:
IIF ( boolean_expression, true_value, false_value )
Example:
SELECT IIF(someColumn = 1, 'yes', 'no')
SQL Server does not have an inline if statement, but it does have an inline case that can be use to accomplish the same.
Case has two forms, one is:
select
case MyFlag
when 1 then 'YES'
when 0 then 'NO'
else 'OOPS'
end
from MyTable
where it's used just like a switch in C-like languages and the other is:
select
case
when MyFlag = 1 then 'YES'
when MyFlag = 0 then 'NO'
-- when some unrelated condition...
else 'OOPS'
end
from MyTable
where it senquentially evaluates a list of conditions and returns the first that is fulfiled.
P.S. The end part is mandatory, and I usually forget that.
It's also usual for a simple case stament to be completely inlined, like
select (case MyFlag when 1 then 'Yes' else 'No' end) as MyFlagDesc
Two possibilities:
(CASE WHEN condition1 THEN Value1 ELSE Value2 END)
or, the most complete solution:
(CASE value_to_check WHEN Value1 THEN Result1 [WHEN ... THEN ...] ELSE OtherResult END)
Something like this:
SELECT
CASE YourColumn
WHEN 0 THEN 'no'
WHEN 1 THEN 'yes'
ELSE 'nothing'
END
FROM dbo.YourTable
I mixed three IIF in one line, I have three variables and I want to know which one is greater than zero but I know the order of priority PersonHomePhoneID , PersonWorkPhoneID and PersonCellPhoneID
IIF(#PersonHomePhoneID > 0 , #PersonHomePhoneID, IIF(#PersonWorkPhoneID > 0 , #PersonWorkPhoneID, IIF(#PersonCellPhoneID > 0 , #PersonCellPhoneID, 0)))
The answer of question :
IIF(column = 1 , 'yes', IIF(column = 0, 'no', ''))

Resources