SQL Syntax for is null or true or both - mysql

I would like to do create a query that shows if one condition is null or the second condition is true but I don't want them to show if they are both true.
IE
If condition one is null or condition 2 is true but don't show if Condition 1 is not null and condition 2 is true.
EG
If Closed is null or NFA is true return the row else if closed is not null and nfa is true don't return the row.
I'm having trouble with the 'else'
WHERE (((Closed) Is Null)) OR (((tblDataDetail.ddt_nfa)=True)) else (???

From your description, I cannot make out whether you are trying to describe XOR, AND or something else. Both MySQL and MS Access support the exclusive or operator so just A XOR B.
Here is a logic table based on your description and possible outcomes:
Closed
ddt_nfa
Closed IS NULL (A)
ddt_nfa = TRUE (B)
A XOR B
A AND B
NULL
FALSE
1
0
1
0
NULL
TRUE
1
1
0
1
1
FALSE
0
0
0
0
1
TRUE
0
1
1
0

Related

How to Assign 0 if Calculated Value is <0 within CASE

I have a MySQL table named users containing simple counts for all users.
user_id
counter1
counter2
1
0
5
2
1
6
3
2
7
4
3
8
I would like to run a single query that updates the counter1 values to counter1-# or 0 (# can be any whole number), whichever is greater for possibly multiple users. The counter1 column is an unsigned int type.
I am executing the following query to update users 2 and 3:
UPDATE
users
SET
counter1 = CASE user_id
WHEN 2 THEN GREATEST(counter1 - 2, 0)
WHEN 3 THEN GREATEST(counter1 - 5, 0)
ELSE counter1 END
WHERE user_id IN(2, 3);
Running the above query returns an error:
BIGINT UNSIGNED value is out of range in '(`user`.`counter1` - 2)'
The end result I'm trying to aim for is for both user 2 and user 3 to have a minimum counter1 value of 0 after the query is executed since in both users' cases, subracting 2/5 from their counter1 values will be a negative number, which of course won't work.
Is there a way to do this with a single query?
The problem is that the expression counter1 - 2 produces a negative value when counter1 is less than 2. But since it's declared UNSIGNED, the result of expressions that use it are also unsigned, so negative values are not allowed.
Instead of subtracting from it, use an IF() expression to prevent calculating these invalid values.
CASE user_id
WHEN 2 THEN IF(counter1 > 2, counter1 - 2, 0)
WHEN 3 THEN IF(counter1 > 5, counter1 - 5, 0)
ELSE counter1
END
Easiest way to do this is:
GREATEST(0, CASE ... END)

Mysql select ignores null values on return results

I have a table where a column is mostly NULL except for one row.
ID STATUS VALUE POS
1 'BAD' 200 0
2 NULL 200 0
3 NULL 300 1
4 'OK' 0 2
if I do
Select * from table where STATUS != 'OK'
I expect
ID STATUS VALUE POS
1 'BAD' 200 0
2 NULL 200 0
3 NULL 300 1
But I get
ID STATUS VALUE POS
1 'BAD' 200 0
I want to know why, I know I can do something else like Where ID = 4, but why the query above returns an empty result for NULL values?
Thanks
Comparing with NULL is always NULL. Think about NULL like it is "unknown value". Does some unknown value is not equal to 'OK'? this is unknown... so the result is NULL.
In logical expressions NULL is treated as FALSE. So you do not receive the rows which you want to receive.
You must either apply additional check for NULL value (WHERE status != 'OK' OR status IS NULL) or convert NULL value to some definite constant value before compare (WHERE COALESCE(status, '') != 'OK').
Pay attention - this interpretation differs from one used in CHECK constraint (including FOREIGN KEY constraint) in which NULL value is treated as "matched".
It isn't possible to use "equal" or "not equal" for NULL values
You MUST use IS NULL or IS NOT NULL e.g:
Select * from table where STATUS != 'OK' OR Status IS NULL

MySQL group by based on column having a given set of data

I want to produce an accurate dataset from mysql based on true and false logic, if I have say 4 rows and a column has status, if in the status any row has a zero the data group should be regarded as false else true
e.g
k | s
--------- //This if i group by k, it returns 1 while i
a 0 //want it to return 0 on group
a 0
a 1
a 1
k | s
--------- //This one if i group by k will return 1 which is very true
a 1
a 1
a 1
a 1
Suggestions
Try this query:
SELECT k,
CASE WHEN SUM(s) < COUNT(s) THEN 0 ELSE 1 END AS label
FROM yourTable
GROUP BY k
This would work well assuming that the only values in the s column are 0 or 1. The logic here is that if even a single row has a zero value, then the SUM(s) for a given k group would be less than the number of records in that group.

SQL case giving inconsistent result

I am getting an inconsistent result from below two SQL queries.
Query1 : select (case when 'Abc' = null then 1 else 0 end) from dual
Query2 : select (case when ('Abc' <> null) then 1 else 0 end) from dual
Result for both queries same i.e
0
What's wrong am I missing some thing ?
NOTE : : I know I can use IS NULL and IS NOT NULL but my question is why result from above queries is inconsistent.
EDIT : Added from answer of #ppeterka.
select (case when null = null then 1 else 0 end) from dual
This returns 0 too. Null is not even equal to itself.
But then what does this return?
select (case when null <> null then 1 else 0 end) from dual
0 again
SQLFiddle link
Because NULL is unknown that is why the result is 0. When you want to compare a column or a value if it is null or not, use IS NULL or IS NOT NULL.
select (case when 'Abc' IS null then 1 else 0 end) from dual -- 0
select (case when ('Abc' IS NOT null) then 1 else 0 end) from dual -- 1
SQLFiddle Demo
The result of comparing anything to NULL, even itself, is always NULL(not TRUE or FALSE).
Searched CASE expression:
If no Boolean_expression evaluates to TRUE, the Database Engine returns the else_result_expression if an ELSE clause is specified, or a NULL value if no ELSE clause is specified.
In your case the result always will be 0, because 0 in ELSE clause
To add a bit of twist to this, try this out:
select (case when null = null then 1 else 0 end) from dual
This returns 0 too. Null is not even equal to itself.
But then what does this return?
select (case when null <> null then 1 else 0 end) from dual
This returns 0 again! Oh holy... It is not even not equal to itself, while it is not equal to itself... Quite a situation to grasp without getting insane...
Why to keep this all in mind? - one might ask
One example is indexing: in Oracle, indexes don't work the way one would expect them to work on NULL values where a column permits the use of that value. This means that given an index, if all the values (fields, functions on fields, etc) of a row that are included in the index are all NULL, that row won't be indexed in that given index. So this means that an index, that has only one value indexed (for example, a field directly), a null value would mean that row not to be included in the index.
To overcome this
it might be advisable to add an index with a distinct, exact value semantically representing the NULL meaning, like NVL(mynullcol,-1) on a column only containing positive integers to be able to query them quickly.
or you could add a constant value to form a "semi-multivalue" index, that indexes all rows, where one can be null, as the other is a constant. (create index idx_myindex on table(column_with_nulls,1); )
(This question and this article detail this subject in a bit more depth)
Another example is ordering...
select (case when null < null then 1 else 0 end) from dual;
select (case when null > null then 1 else 0 end) from dual;
Both 0. This is OK... We expected this by now... And what about this?
select (case when 'Abc' > null then 1 else 0 end) from dual;
select (case when null > 'Abc' then 1 else 0 end) from dual;
Uh-oh... Both 0 again. This might be an issue - how is ordering going to work?
select col_1 from
(select null as col_1 from dual)
union all (select 'Abc' as col_1 from dual)
union all (select null as col_1 from dual)
union all (select null as col_1 from dual)
order by col_1
This however consistently returns:
Abc
null
null
null
Using ... order by col_1 DESC returns:
null
null
null
Abc
So from this, on an empirical basis, it does seem that 'Abc' < null... However, as per the valuable comment of #ypercube:
the sort order can be set with the NULLS LAST and NULLS FIRST modifiers (at least in Oracle).
What you observe is the default sort order when the ORDER BY has no modifier
NULL is a twisted business, it is wise to steer away from it if it is possible... (And this is not only true for SQL, but for certain situations in OOP languages too.)
You can't use <> or = with nulls. You need to say
select (case when 'Abc' is null then 1 else 0 end) from dual
and
select (case when 'Abc' is not null then 1 else 0 ) from dual
It is not inconsistent.
if you have 2 objects A,B then it's one of the following three:
A equals B
A not equals B
you cannot compare A and B
It's like examining if (0/0 > 0) or (0/0 < 0) or (0/0 = 0). You just cannot compare them. every option is false
For your example: case checks if your argument is true
argument ('abc'=null) is not true, it's null
argument ('abc'<>null) is not true, it's null
The value NULL means the data value for the column is Unknown. A NULL is not synonymous with Zero, or zero length string or blank.
Anything you compare with NULL will result in Unknown (NULL).
Please check this to clear your doubts. To have the correct result, use IS NULL or IS Not NULL as you already know.

Return 1 or 0 if mysql column has data

I would like to return 1 or 0 (or true or false, or true or null, or whatever is easiest) if a given column has any data. Regardless of whether this field has data, the other columns would still be returned. Is below the correct way? Thanks
SELECT varchar_field IS NOT NULL, some_other_fields
Try
SELECT ISNULL(varchar_field), some_other_fields
if you want 0 when varchar_field isnt null
SELECT NOT ISNULL(varchar_field), some_other_fields
if you want 1 when varchar_field isnt null
You can use case statement
CASE WHEN varchar_field is null
THEN 1
ELSE 0
END