Why does this give me 1 which is what I was expecting:
IF (SELECT 123) = 123
PRINT 1
ELSE
PRINT 2
But this gives me 2 which I was not expecting:
IF (SELECT NULL) = NULL
PRINT 1
ELSE
PRINT 2
NULL values are checked by IS NULL
you have to use:
IF (SELECT NULL) IS NULL
PRINT 1
ELSE
PRINT 2
from the manual:
To search for column values that are NULL, you cannot use an expr =
NULL test. The following statement returns no rows, because expr =
NULL is never true for any expression
If you put NULLS OFF
SET ANSI_NULLS OFF
IF (SELECT NULL) = NULL
PRINT 1
ELSE
PRINT 2
then you will get PRINT 1
You cant check NULL with =. For that IS has to be used.
Ex:
IF (SELECT NULL) IS NULL
PRINT 1
ELSE
PRINT 2
You cannot check NULL using =. You need to use IS NULL like the following
IF (SELECT NULL) IS NULL
PRINT 1
ELSE
PRINT 2
Related
In this project I'm currently working on (I'm building a bridge between a desktop app and a new e-shop) there is a products table that has some spare columns defined that can be used for whatever reason the end user might need some custom data to be stored into.
So, the user needed to set a true/false flag to determine whether the products would appear in three different sliders... Unfortunately, the person who implemented this, didn't even use the same type of spare columns... So,
Slider1's flag is stored in a varchar(50) column
Slider2's flag is stored in a float column
Slider3's flag is stored in a float column
Additionally I ran a SELECT DISTINCT <column> for each one of them to get an idea of the actual data stored in each column and got the following results:
The varchar column has the following data stored in it:
FLDSTRING1
NULL
''
0
1
194276400456
The float column has the following data stored:
FLDFLOAT5
NULL
0
1
And the other float column has this:
FLDFLOAT6
NULL
1
Also, I ran the following query to find the different combinations of the data stored for each column:
SELECT FLDSTRING1, FLDFLOAT5, FLDFLOAT6
FROM MATERIAL
GROUP BY FLDSTRING1, FLDFLOAT5, FLDFLOAT6
and got the following combinations...
FLDSTRING1
FLDFLOAT5
FLDFLOAT6
NULL
NULL
NULL
NULL
NULL
1
NULL
0
NULL
NULL
1
NULL
NULL
1
1
''
NULL
NULL
''
NULL
1
0
NULL
NULL
0
0
NULL
1
NULL
NULL
1
NULL
1
1
0
NULL
1
1
NULL
1
1
1
194276400456
0
NULL
What I need after all this introduction...
I want a concatenated string of three comma-separated values like this
NEWPROD for when FLDSTRING1 would evaluate to true - anything not NULL, 0, or ''
CUSTOM1 for when FLDFLOAT5 would evaluate to true - basically the value 1
CUSTOM2 for when FLDFLOAT6 would evaluate to true - again value 1
After some trial and error I managed to bring this to a point that it kind of works, in the sense that it brings the correct values, not comma-separated though...
SELECT
FLDSTRING1, FLDFLOAT5, FLDFLOAT6,
CONCAT(CASE WHEN ISNULL(FLDSTRING1, '') = '' THEN '' ELSE 'NEWPROD' END,
CASE WHEN ISNULL(FLDFLOAT5, '') = '' THEN '' ELSE 'CUSTOM1' END,
CASE WHEN ISNULL(FLDFLOAT6, '') = '' THEN '' ELSE 'CUSTOM2' END) AS TAGS
FROM
MATERIAL
GROUP BY
FLDSTRING1, FLDFLOAT5, FLDFLOAT6;
FLDSTRING1
FLDFLOAT5
FLDFLOAT6
TAGS
NULL
NULL
NULL
NULL
NULL
1
CUSTOM2
NULL
0
NULL
NULL
1
NULL
CUSTOM1
NULL
1
1
CUSTOM1CUSTOM2
''
NULL
NULL
''
NULL
1
CUSTOM2
0
NULL
NULL
NEWPROD
0
0
NULL
NEWPROD
1
NULL
NULL
NEWPROD
1
NULL
1
NEWPRODCUSTOM2
1
0
NULL
NEWPROD
1
1
NULL
NEWPRODCUSTOM1
1
1
1
NEWPRODCUSTOM1CUSTOM2
194276400456
0
NULL
NEWPROD
Problem #1 is I don't quite understand how this works... I mean, value 0 isn't '', but still for the combination of NULL 0 NULL I get an empty value, which is what I wanted... But how does it do that?
And also, can someone update my final query to comma-separate the calculated TAGS column? Problem #2 is that I don't want it to contain just two commas, like ,,, when the combination wouldn't justify any of the three values to appear... It should work like PHP's implode() works...
To help you help me with this, I'm including a fiddle with the setup of the scenario I describe here... Thanks in advance!
Since you are using SQL Server 2014, instead of CONCAT_WS you may try STUFF as shown below. By prepending the delimiter , before all strings ,the STUFF will remove the first comma found.
SELECT
FLDSTRING1,
FLDFLOAT5,
FLDFLOAT6,
STUFF(
CONCAT(
CASE WHEN FLDSTRING1 IS NULL OR FLDSTRING1 IN ('0','') THEN '' THEN '' ELSE ',NEWPROD' END,
CASE WHEN FLDFLOAT5 IS NULL THEN '' ELSE ',CUSTOM1' END,
CASE WHEN FLDFLOAT6 IS NULL THEN '' ELSE ',CUSTOM2' END
),
1,1,''
) AS TAGS
FROM #MATERIAL
GROUP BY FLDSTRING1, FLDFLOAT5, FLDFLOAT6;
View working demo db fiddle
Let me know if this works for you.
Use the CONCAT_WS() function to concat values into a comma (or other separator) separated list, which ignores nulls.
To use CONCAT_WS(), you want to pass it a true NULL if the value is "blank" (by your definition), otherwise your custom label:
SELECT DISTINCT
FLDSTRING1,
FLDFLOAT5,
FLDFLOAT6,
CONCAT_WS(',',
CASE WHEN FLDSTRING1 IS NULL OR FLDSTRING1 = '' OR FLDSTRING1 = '0' THEN NULL ELSE 'NEWPROD' END,
CASE WHEN FLDFLOAT5 IS NULL OR FLDFLOAT5 = 0 THEN NULL ELSE 'CUSTOM1' END,
CASE WHEN FLDFLOAT6 IS NULL OR FLDFLOAT6 = 0 THEN NULL ELSE 'CUSTOM2' END) AS TAGS
FROM MATERIAL
Replaced GROUP BY with DISTINCT because it's simpler and (here) achieves the same thing.
If CONCAT_WS is not available:
SELECT DISTINCT
FLDSTRING1,
FLDFLOAT5,
FLDFLOAT6,
REPLACE(REPLACE(REPLACE(CONCAT(
CASE WHEN FLDSTRING1 IS NULL OR FLDSTRING1 = '' OR FLDSTRING1 = '0' THEN 'X' ELSE 'NEWPROD' END,
',',
CASE WHEN FLDFLOAT5 IS NULL OR FLDFLOAT5 = 0 THEN 'X' ELSE 'CUSTOM1' END,
',',
CASE WHEN FLDFLOAT6 IS NULL OR FLDFLOAT6 = 0 THEN 'X' ELSE 'CUSTOM2' END
), ',X', ''), 'X,', ''), 'X', '') AS TAGS
FROM MATERIAL
See dbfiddle.
I'm handing lots of data and error checking it to ensure that it follows a correct format. So I'm creating a lot of IF conditions and so far I can group lots of conditions but only output one kind of error .. or i end up writing a heck of a lot of code per condition, just to have a crystal clear error output.
Is there a way to put into the IF condition a specific error output string?
Here is my code:
-- set the initial #IntHosp_SUM value
SELECT #IntHosp_SUM = 0
-- Store the sum value to #IntHosp_SUM
SELECT #IntHosp_SUM =
(
(COALESCE (CASE WHEN #Int1_5hosp = 1 THEN COUNT (Int1_5) ELSE NULL END, 0)) +
(COALESCE (CASE WHEN #Int2_5hosp = 1 THEN COUNT (Int2_5) ELSE NULL END, 0)) +
(COALESCE (CASE WHEN #Int3_5hosp = 1 THEN COUNT (Int3_5) ELSE NULL END, 0)) +
(COALESCE (CASE WHEN #Int4_5hosp = 1 THEN COUNT (Int4_5) ELSE NULL END, 0)) +
(COALESCE (CASE WHEN #Int5_5hosp = 1 THEN COUNT (Int5_5) ELSE NULL END, 0)) +
(COALESCE (CASE WHEN #Int6_5hosp = 1 THEN COUNT (Int6_5) ELSE NULL END, 0))
)
FROM ASSSIST2_M0Teacher
-- Check RESUSE_SUM Value against Intervention Entries
SELECT #ErrorID = IsNull(Max(ErrorID) + 1, 1)
FROM ErrorTemp
WHERE (Quest = #DB + #Quest) AND (ValidateID = #ValidateID)
SELECT #Error = 0
IF (#IntHosp_SUM = 1 and #Hosp1_info is null )
or (#IntHosp_SUM = 2 and (#Hosp1_info is null or #Hosp2_info is null))
or (#IntHosp_SUM >=3 and (#Hosp1_info is null or #Hosp2_info is null or #Hosp3_info is null))
or (#IntHosp_SUM = 0 and (#Hosp1_info is not null or #Hosp2_info is not null or #Hosp3_info is not null ))
or (#IntHosp_SUM = 1 and (#Hosp2_info is not null or #Hosp3_info is not null ))
or (#IntHosp_SUM >= 2 and #Hosp3_info is not null)
BEGIN
SELECT #Error = 1
END
BEGIN
IF #Error = 1
INSERT INTO ErrorTemp
(Quest,
ValidateID,
ErrorID,
ErrorType,
ErrorDesc,
Field)
VALUES (#DB + #Quest,
#ValidateID,
#ErrorID,
'Validation',
'Too much or no info present, so incorrect',
'Hosp Info - admissions')
SELECT #ErrorID = #ErrorID + 1
END
I have declared all variables and where they are in the DB, but didn't want to clutter with extra code. You can see that I sum a series of fields if they contain the value 1 .. I don't want to add any other values, just those with '1'.
My IF conditions then check if that if there is a sum of 1, there is one entry. If 2, then two entries .. we have to be thorough and check the inverse of that, so if the sum value is 0, then no entries are made and so forth.
Is there a way to pass a string from the IF / OR condition to the error output so that I can write a unique error per condition?
SQL Server Management Studio 17.2
i an new in vb.ner sql and what i am asking may be silly question. I have a table in sql server 2005 and a column name activated. this column contain NULL, true or false.
I want to select only NULL or false values. How can i do this?
The selection should be done on the SQL Server's side. Your query should look like this:
SELECT *
FROM MyTable
WHERE activated = 0 OR activated is NULL
The above assumes that the column activated is of an integral or a BIT data type.
Note: it may be tempting to use a seemingly equivalent WHERE activated <> 1 condition. This would be incorrect, though, because comparisons of NULL values to anything result in a NULL, so the rows with activated = NULL would be excluded.
You should be able to do a coalesce on the field to get it to false if it is null. A coalesce statement checks to see if the first parameter is null, if it is it returns the value in the second parameter. There would be two solutions:
SELECT *
FROM MyTable
WHERE COALESCE(activated,'false') <> 'true'`
--OR--
SELECT *
FROM MyTable
WHERE activated = 'false' or activated is null
With SQL's 3-valued logic, comparisons for NULL need to be done using the IS NULL operator... the check for false can be done with =:
SELECT YourColumn
FROM YourTable
WHERE
YourColumn IS NULL
OR YourColumn = 0
SELECT * FROM MyTable WHERE isnull(activated, 0) = 0
For checking NULL you have to use the keyword "IS NULL" and for false =0 like below
SELECT * FROM MyTable WHERE activated = 0 OR activated is NULL
Sometimes you have to see it to believe...
PRINT '0 = 0' ; IF 0 = 0 PRINT 'true' ELSE PRINT 'false';PRINT '';
PRINT '0 = 1' ; IF 0 = 1 PRINT 'true' ELSE PRINT 'false';PRINT '';
PRINT '0 = NULL' ; IF 0 = NULL PRINT 'true' ELSE PRINT 'false';PRINT '';
PRINT '1 = NULL' ; IF 1 = NULL PRINT 'true' ELSE PRINT 'false';PRINT '';
PRINT 'NULL = NULL' ; IF NULL = NULL PRINT 'true' ELSE PRINT 'false';PRINT '';
PRINT 'NULL IS NULL'; IF NULL IS NULL PRINT 'true' ELSE PRINT 'false';PRINT '';
The SQL way is to use IS TRUE or similar:
SELECT * FROM MyTable WHERE activated = 0 IS NOT FALSE
I have the following #temp table :
SELECT *
FROM #temp
WHERE LinkingID = 1
------------------------------------------------------------------
|Condition_ID LinkingID Operator Variable1 Variable2 |
| 1 1 == 25 2 |
| 2 1 <> 3 7 |
| 3 1 == 4 4 |
------------------------------------------------------------------
I want to implement a CASE ( ??? ) that will check if Variable1 OPERATOR Variable2 is true, make the check for all rows and IF all rows are true then do something, else break off and abort.
I was thinking something like this ( I'm not sure how to express this in T-SQL so I use pseudolanguage ) :
CASE
WHEN Operator LIKE '=='
THEN IF Variable1 == Variable2 THEN TRUE
ELSE THEN FALSE
WHEN Operator LIKE '<>'
THEN IF Variable1 <> Variable2 THEN TRUE
ELSE THEN FALSE
FROM #temp
If the result of this is true for all rows, then do something, else do something else
In the scenario above :
Row1 would return FALSE
Row2 would return TRUE
Row3 would return TRUE
Hence the result is FALSE.
Accumulating comparison results over the whole table
Checking that the whole table returns true for all rows is best done to count false ones and check whether that number is greater equal to 0. If it's 0 then it means that all rows matched otherwise number indicates number of rows that failed
Mind the inverted comparison compared to Operator value to catch negatives:
declare #NonMatched int
select
#NonMatched = sum(
case
when [Operator] = '==' and Variable1 <> Variable2 then 1
when [Operator] = '<>' and Variable1 = Variable2 then 1
else 0
end
)
from #temp
where LinkingID = 1
if #NonMatched = 0
begin
-- execute your stored procedure or whatever else set of statements
end
Here's also a SQLFiddle that's based on upper code.
Im going to go out on a limb and guess you're trying to do something with all rows which the conditional variable 1 [operator] variable2 evaluates true. This could be selecting them, or deleting them - it makes no difference really.
I'll use a select as the example:
SELECT *
FROM #temp
WHERE LinkingID = 1
AND CASE Operator
WHEN '==' THEN Variable1 = Variable2
WHEN '<>' THEN Variable1 <> Variable2
END
The same where clause could be used if you wanted to delete these records.
EDIT To aggregate up this set and do something when all conditions for a particular LinkingID evaluate true, something like this will work:
IF EXISTS(
SELECT LinkingID FROM temp
WHERE LinkingID = 1
GROUP BY LinkingId
HAVING SUM(CASE
WHEN Operator = '==' AND Variable1 = Variable2 THEN 1
WHEN Operator = '<>' AND Variable1 <> Variable2 THEN 1
ELSE 0
END) = count(*)
)
BEGIN
-- Do something
END
Live example to play with here: http://www.sqlfiddle.com/#!6/26d72/6
In that example I have set up LinkingID=2 where all conditions are true. Change the LinkingId=1 to =2 to see the do something message.
I would write something like this:
SELECT
CASE WHEN NOT EXISTS
( SELECT *
FROM #temp
WHERE LinkingID = 1
AND NOT ( Operator = '==' AND Variable1 = Variable2
OR Operator = '<>' AND Variable1 <> Variable2
)
) THEN 'TRUE'
ELSE 'FALSE'
END AS Result ;
I have a procedure which receive a bit variable called #FL_FINALIZADA.
If it is null or false I want to restrict my select to show only the rows that contain null DT_FINALIZACAO values. Otherwise I want to show the rows containing not null DT_FINALIZACAO values.
Something like this:
SELECT
*
FROM
MyTable
WHERE
...
AND
(
OPE.DT_FINALIZACAO = (
CASE
WHEN (#FL_FINALIZADA <> 1)
THEN NULL
END
) OR
OPE.DT_FINALIZACAO IS NOT NULL
)
In this case I receive the message:
None of the result expressions in a
CASE specification can be NULL.
How can I achieve this?
Thanks in advance.
SELECT
*
FROM
MyTable
WHERE
(ISNULL(#FL_FINALIZADA, 0) = 0
AND
OPE.DT_FINALIZACAO IS NULL
)
OR
(#FL_FINALIZADA = 1
AND
OPE.DT_FINALIZACAO IS NOT NULL
)
Change the AND to be:
AND (((#FL_FINALIZADA <> 1) AND (OPE.DT_FINALIZACAO IS NULL)) OR ( (#FL_FINALIZADA = 1) AND (OPE.DT_FINALIZACAO IS NOT NULL)))
If the bit flag is 1 then DT_FINALIZACAO can't be null.
IF #FL_FINALIZADA IS NULL
SET #FL_FINALIZADA = 0
SELECT * FROM NewsletterSubscribers
WHERE
(#FL_FINALIZADA = 0 AND OPE.DT_FINALIZACAO IS NULL)
OR
(#FL_FINALIZADA = 1 AND OPE.DT_FINALIZACAO IS NOT NULL)
My detailed SQL is a little rusty, but have you tried using 0 insted of NULL? I would expect 0 to evaluate the same as NULL in that select