Update Zero to One and One to Zero in SQL Server - sql

I have a table with flag 0 and 1.
Please tell me how to update Zero to One and One to Zero
DECLARE #a INT, #b INT
SELECT #a = number
FROM zerone
WHERE number = 0
SELECT #b = number
FROM zerone
WHERE number = 1
BEGIN
IF #a = 0
UPDATE zerone
SET number = 1
WHERE #a = 0
ELSE IF #b = 1
UPDATE zerone
SET number = 0
WHERE #b = 1
END
This query is not working for me.

use the below query to update 0 to 1 and 1 to 0
update zerone set number= 1-number

Just this:
UPDATE zerone
SET number = CASE WHEN number = 1 THEN 0 ELSE 1 END;

you should also always consider NULL values in update operations and must explicitly filter them out
UPDATE zerone
SET number= case
when 1 then 0
when 0 then 1
end
WHERE number in (0,1)
Also your query will not work because you are assigning a single variable with a rows of data in the select statement.
SELECT #a = number
FROM zerone
WHERE number = 0
This does not work like as you are expecting and will only assign #a with value either NULL(if there are no rows) or with 0 if there is a row. If there are multiple rows even then it will have a single value 0

As you have seen there are so many ways to perform that task but in this case, I would prefer #Abdul Rasheed.
We can also use below IIF logical function in SQLSERVER2012 or above.
UPDATE zerone
SET number = IIF (number = 1, 0, 1)

Related

can we set multiple values in variable in sql

DECLARE #a int
SET #a = 5
SET #a = CASE
WHEN #a >= 5 THEN 1
WHEN #a <= 5 THEN 2
WHEN a < 10 THEN 3
END
SELECT #a
#a value should be 3, but why it is showing 1?
Can anyone explain how it works?
I have been asked same question one of SQL interview
Case expression will Evaluates, as order you specified :
So, you want prioritized when clause :
case when #a < 10 then 3
when #a <= 5 then 2
when #a >= 5 then 1
end
The CASE statement goes through conditions and returns a value when the first condition is met. Following two way of your problem should be solved, you can try one of them.
declare #a int
set #a=5
set #a= case when #a>5 then 1
when #a<5 then 2
when #a <10 then 3 end
select #a
set #a=5
set #a= case when #a <10 then 3
when #a>=5 then 1
when #a<=5 then 2 end
select #a

SQL input value either single or multiple values

In SQL query if the input value is 0 then take input as all values of the column else consider input value only;
Let's say if the input city_num = 0 then run the query for all city numbers i.e 1 to 50 else run the query for the input city_num say 5.. How to code this?
if the City_num = 0 then Select * from emp where City_num in 1to 50
if the City_num = 5 then Select * from emp where City_num = 5
;
Add this WHERE statement:
WHERE city_num = ? OR 0 = ?
If you pass 0 then it is equivalent to:
WHERE city_num = 0 OR 0 = 0
and since 0 = 0 is always TRUE then it will fetch all the rows.
If you pass 5 then it is equivalent to:
WHERE city_num = 5 OR 0 = 5
and since 0 = 5 is always FALSE then it will fetch only the row for city_num = 5.
Try This:
DECLARE #input INT = 2;
SELECT * FROM TABLE1
WHERE (city_num= #input AND #input > 0) OR #input = 0;
I have assumed city_num is integer. Minor fix if varchar

Dynamic TOP N / TOP 100 PERCENT in a single query based on condition

A local variable #V_COUNT INT. If the variable #V_COUNT is '0'(zero) the return all the records from table otherwise return the number of {#V_COUNT} records from table. For example if #V_COUNT = 50, return TOP 50 records. If #V_COUNT is 0 then return TOP 100 PERCENT records. Can we achieve this in a single query?
Sample query :
DECLARE #V_COUNT INT = 0
SELECT TOP (CASE WHEN #V_COUNT > 0 THEN #V_COUNT ELSE 100 PERCENT END) *
FROM MY_TABLE
ORDER BY COL1
Incorrect syntax near the keyword 'percent'
A better solution would be to not use TOP at all - but ROWCOUNT instead:
SET ROWCOUNT stops processing after the specified number of rows.
...
To return all rows, set ROWCOUNT to 0.
Please note that ROWCOUNT is recommended to use only with select statements -
Important
Using SET ROWCOUNT will not affect DELETE, INSERT, and UPDATE statements in a future release of SQL Server. Avoid using SET ROWCOUNT with DELETE, INSERT, and UPDATE statements in new development work, and plan to modify applications that currently use it. For a similar behavior, use the TOP syntax.
DECLARE #V_COUNT INT = 0
SET ROWCOUNT #V_COUNT -- 0 means return all rows...
SELECT *
FROM MY_TABLE
ORDER BY COL1
SET ROWCOUNT 0 -- Avoid side effects...
This will eliminate the need to know how many rows there are in the table
Be sure to re-set the ROWCOUNT back to 0 after the query, to avoid side effects (Good point by Shnugo in the comments).
Instead of 100 percent you can write some very big number, which will surely be bigger than possible number of rows returned by the query, eg. max int which is 2147483647.
You can do something like:
DECLARE #V_COUNT INT = 0
SELECT TOP (CASE WHEN #V_COUNT > 0 THEN #V_COUNT ELSE (SELECT COUNT(1) FROM MY_TABLE) END) *
FROM MY_TABLE
DECLARE #V_COUNT int = 3
select *
from
MY_TABLE
ORDER BY
Service_Id asc
offset case when #V_COUNT >0 then ((select count(*) from MY_TABLE)- #V_COUNT) else #V_COUNT end rows
SET ROWCOUNT forces you into procedural logic. Furthermore, you'll have to provide an absolute number. PERCENT would need some kind of computation...
You might try this:
DECLARE #Percent FLOAT = 50;
SELECT TOP (SELECT CAST(CAST((SELECT COUNT(*) FROM sys.objects) AS FLOAT)/100.0 * CASE WHEN #Percent=0 THEN 100 ELSE #Percent END +1 AS INT)) o.*
FROM sys.objects o
ORDER BY o.[name];
This looks a bit clumsy, but the computation will be done once within microseconds...

coalesce and a case statement - explanation?

I'm working on a query that doesn't seem to be doing what it's supposed to since being transferred from one SSRS server to another, and the following line in part of the where statement appears to be where the difference is, or at least from what I can find.
where COALESCE(field, -1) = CASE field WHEN 1 THEN 0 ELSE -1 END
I know it's probably a bit generic but can anyone shed any light on what this may be doing? I've read up on coalesce and gather that it finds the first non-null value from the specified list of fields, but I don't understand what the '-1' does there.
I hope it's not too general a question and that someone can give me a clue as to what it may be doing
Without context it's difficult to give a truly helpful answer.
At first glance it looks as though it could be rewritten much more simply from this:
WHERE COALESCE(#field, -1) = CASE #field WHEN 1 THEN 0 ELSE -1 END
to this:
WHERE COALESCE(#field, -1) = -1
If that is true then basically you are saying that if the field is null or the field equals -1 then the condition is true otherwise it's false.
Here are some tests to try to prove this:
-- Original
DECLARE #field INT
SELECT 1 WHERE COALESCE(#field, -1) = CASE #field WHEN 1 THEN 0 ELSE -1 END
SET #field = -1
SELECT 1 WHERE COALESCE(#field, -1) = CASE #field WHEN 1 THEN 0 ELSE -1 END
SET #field = 0
SELECT 1 WHERE COALESCE(#field, -1) = CASE #field WHEN 1 THEN 0 ELSE -1 END
SET #field = 1
SELECT 1 WHERE COALESCE(#field, -1) = CASE #field WHEN 1 THEN 0 ELSE -1 END
SET #field = 2
SELECT 1 WHERE COALESCE(#field, -1) = CASE #field WHEN 1 THEN 0 ELSE -1 END
SET #field = 3
SELECT 1 WHERE COALESCE(#field, -1) = CASE #field WHEN 1 THEN 0 ELSE -1 END
--Rewritten
DECLARE #field INT
SELECT 1 WHERE COALESCE(#field, -1) = -1
SET #field = -1
SELECT 1 WHERE COALESCE(#field, -1) = -1
SET #field = 0
SELECT 1 WHERE COALESCE(#field, -1) = -1
SET #field = 1
SELECT 1 WHERE COALESCE(#field, -1) = -1
SET #field = 2
SELECT 1 WHERE COALESCE(#field, -1) = -1
SET #field = 3
SELECT 1 WHERE COALESCE(#field, -1) = -1
Both sets of queries in this test give the same results, but as I said without context and realistic test data it's difficult to know if there was a reason why the query was written in the way that it originally was.
Here is another example from a different perspective, using a LEFT JOIN:
DECLARE #MainTable AS TABLE(ident INT)
DECLARE #PossibleNullTable AS TABLE(mainIdent INT, field INT)
INSERT INTO #MainTable(ident) VALUES(1)
INSERT INTO #MainTable(ident) VALUES(2)
INSERT INTO #MainTable(ident) VALUES(3)
INSERT INTO #MainTable(ident) VALUES(4)
INSERT INTO #MainTable(ident) VALUES(5)
INSERT INTO #PossibleNullTable(mainIdent, field) VALUES(1,-1)
INSERT INTO #PossibleNullTable(mainIdent, field) VALUES(1,1)
INSERT INTO #PossibleNullTable(mainIdent, field) VALUES(1,0)
INSERT INTO #PossibleNullTable(mainIdent, field) VALUES(2,0)
INSERT INTO #PossibleNullTable(mainIdent, field) VALUES(3,1)
INSERT INTO #PossibleNullTable(mainIdent, field) VALUES(5,-1)
--Original
SELECT *
FROM #MainTable mt
LEFT JOIN #PossibleNullTable pnt
ON mt.ident = pnt.mainIdent
WHERE COALESCE(field, -1) = CASE field WHEN 1 THEN 0 ELSE -1 END
--Original Result
ident mainIdent field
1 1 -1
4 NULL NULL
5 5 -1
--Rewritten
SELECT *
FROM #MainTable mt
LEFT JOIN #PossibleNullTable pnt
ON mt.ident = pnt.mainIdent
WHERE COALESCE(field, -1) = -1
--Rewritten Result
ident mainIdent field
1 1 -1
4 NULL NULL
5 5 -1
Again both queries in this test give the same results.
the first non-null value from the specified list of fields
This means the list of fields between the parenthesis. For instance:
COALESCE(col1,col2,col3,-1)
means that if col1 is not null then use this, else check col2. If col2 is null then check col3. If that is null too then use -1 as the value.
In your example, COALESCE(field, -1) is equivalent to ISNULL(field, -1)
In my example COALESCE(col1,col2,col3,-1) is equivalent to ISNULL(ISNULL(ISNULL(col1, col2), col3), -1)
This is a bit complex expression used in where clause, that suggests
use field column, replace NULL values with -1 & compare all these values of field column with the case expression such as,
here at first, we have to consider that there is no null value in field column as we have replaced all null with -1 using coalesce().
then in case statement, if the values is 1 then it is replace by 0. So 0 is checked with coalesce(field,-1), if it is also 0, then expression is true else false.
Similar for field value -1 using case.

Use comparison signs inside a sql case statement

I'm looking for a way to build case statements in a sql select query using less than and greater than signs. For example, I want to select a ranking based on a variable:
DECLARE #a INT
SET #a = 0
SELECT CASE
WHEN #a < 3 THEN 0
WHEN #a = 3 THEN 1
WHEN #a > 3 THEN 2
END
I'd like to write it as:
DECLARE #a INT
SET #a = 0
SELECT CASE #a
WHEN < 3 THEN 0
WHEN 3 THEN 1
WHEN > 3 THEN 2
END
...but SQL doesn't let me use the < and > signs in this way. Is there a way that I can do this is SQL 2005, or do I need to use the code like in the first one.
The reason for only wanting the code there once is because it would make the code a lot more readable/maintainable and also because I'm not sure if SQL server will have to run the calculation for each CASE statement.
I'm looking for a VB.NET case statement equivelent:
Select Case i
Case Is < 100
p = 1
Case Is >= 100
p = 2
End Select
Maybe it's not possible in SQL and that's ok, I just want to confirm that.
You can use the SIGN function as
DECLARE #a INT
SET #a = 0
SELECT CASE SIGN(#a - 3)
WHEN -1 THEN 0
WHEN 0 THEN 1
WHEN 1 THEN 2
END
If #a is smaller than 3, then #a - 3 results in a negative int, in which SIGN returns -1.
If #a is 3 or greater, then SIGN returns 0 or 1, respectively.
If the output you want is 0, 1 and 2, then you can simplify even more:
DECLARE #a INT
SET #a = 0
SELECT SIGN(#a - 3) + 1
Using SIGN as suggested by #Jose Rui Santos seems a nice workaround. An alternative could be to assign the expression an alias, use a subselect and test the expression (using its alias) in the outer select:
SELECT
…,
CASE
WHEN expr < 3 THEN …
WHEN expr > 3 THEN …
END AS …
FROM (
SELECT
…,
a complex expression AS expr
FROM …
…
)
SELECT
CASE
WHEN ColumnName >=1 and ColumnName <=1 THEN 'Fail'
WHEN ColumnName >=6 THEN 'Pass'
ELSE 'Test'
END
FROM TableName