Why 'NOT LIKE' does not work with OR in SQL [closed] - sql

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
Why below query does not return CategoryName and Description excluding the record whose Description starts with S and D. But when I replace OR with AND it works.
SELECT CategoryName, Description
FROM [Categories]
Where Description NOT LIKE 'S%'
OR Description NOT LIKE 'D%'

You really want AND instead of OR. But in SQL Server this is more simply written as:
Where Description NOT LIKE '[DS]%'

The reason it doesn't work is you are dealing with boolean logic.
Your query is asking if it is 'not like apples or not like oranges'
OR means both boolean statements need to be false in order to be false (or either needs to be true to be true) depending on your point of view.
if you have an apple it is not like and orange so your boolean logic is 1 or 0 which results in 1 or true.
That is why you want and so you need bothe to be 1 to pass the boolean logic.

Taking SQL out of this, this is a classic application of DeMorgan's Law.
In this case, it looks like you want "Descriptions that start with neither S nor D". Translating that into Boolean logic, that's:
(Description NOT «start with S») AND (Description NOT «start with D»)
Which is equivalent to
NOT ((Description «start with S») OR (Description «start with D»))
In this case, each of the two statements that I'm saying are equivalent is easily translated to SQL - use whichever of them makes the most sense.

It would be nice if you could just stick some wildcards in the in clause like this:
where column1 not in ('%value1%','%value2%','%value3%')
But, you can’t stick a wildcard inside of the IN clause. So, here is the easiest solution.
select *
from table1
where column1 not like '%value1%'
and column1 not like '%value2%'
and column1 not like'%value3%';
Basically you are trying to replace in ( value1 AND value2 AND value3 )
with OR logical operator,
That is why this will not work.
after you replace OR with AND you should get this results:
Link to full description of the problem and the solution

Related

How to convert varchar format into integer format with NULLs in column in SQL [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 months ago.
Improve this question
I have a column with a varchar(255) format.
The column has number values and NULL values.
I need to convert the column to an integer format, but it fails because of the NULL values.
I have looked it up online and this issue is stated many places. But I can't seem to find the right solution. The solution has to work in a Microsoft SQL server enviroment.
I have tried this:
CAST(varcharname AS INT) AS varname
CAST(CASE WHEN varcharname IS NOT NULL THEN varcharname ELSE NULL END AS INT) AS varname
CAST(NULLIF(varcharname , '') AS INT) AS varname
CAST(NULLIF(varcharname , NULL) AS INT) AS varname
The problem is not the null values, and I can prove it:
https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=c6734d0967eae022b0af2ee3a2b694db
More likely there is something else in the column that fails the conversion. Perhaps some whitespace? Remember that an empty string is not the same as NULL, and a string with only whitespace is not the same as an empty string.
Try this:
cast(nullif(rtrim(varcharname),'') as int)
One other thing to consider is if there is more data in the column and you are restricting results with a WHERE clause.
For example, let's say you have this data:
id
varcharname
1
'1'
2
NULL
3
'3'
4
'4'
5
'Five'
You may have a query with WHERE clause condition like this:
SELECT cast(varcharname as int) WHERE id <> 5
hoping to get results like this:
~
1
NULL
3
4
This solution will often (not always!) still fail, because the database may decide it's more efficient to apply the cast before the WHERE clause.
In this case (or if the earlier solution don't work) you can use TRY_CAST().
However, rather than use TRY_CAST() to merely smooth over your errors, first look to find out which rows/values are causing the errors (so you can fix them, and also fix whatever upstream process saved the bad data):
SELECT [id], varcharname
FROM [MyTable]
WHERE TRY_CAST(varcharname as int) IS NULL and varcharname IS NOT NULL
Finally, remember it's very poor practice to use varchar columns to store number (or date) data in the first place, to the point I consider such schemas to be broken.

Need to change field value from blank to "Unknown" in MS Access [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I need to replace all blank records within a query with "Unknown"
Tried setting the default value to "Unknown" but that did not work
Desired outcome:
"Blank" Records -> "Unknown" Records
Created an update query to replace Null values with "Unknown"
You can use IIF and Isnull to default null values to unknown - e.g.
select iif(isnull(field1), 'Unknown', field1),
iif(isnull(field2), 'Unknown', field2) from table1
(effectively saying if field1 is null return Unknown, otherwise return field 1)

divide by zero in specific case in sql server [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 4 years ago.
Improve this question
I am getting Divide by zero error for the following statement.
select ((((57151130.0000000000)+(57612530.0000000000))/2)/((12548020.0000000000)-(34321580.0000000000)+(21773560.0000000000)))*366
The fact that you are supplying literal values is a little odd, however, one method of avoiding a divide by 0 error is using NULLIF (Transact-SQL).
NULLIF takes 2 parameters. If the values of the 2 expressions for the parameters are the same value, then NULLIF returns NULL, otherwise it returns the value of the first expression. For example (in literal terms):
SELECT NULLIF(1,0), NULLIF('a' + 'b' + 'c','abc');
This returns the values 1 and NULL. For your query, the format would therefore be:
SELECT (((57151130.0000000000+57612530.0000000000)/2)/NULLIF(12548020.0000000000-34321580.0000000000+21773560.0000000000,0))*366
Note I have removed several of the parenthesis as there's no need to wrap every value/expression in a pair. Doing so will likely lower readability.
Then, if the expression under the divisor has the value 0, the value NULL will be returned instead. Considering that NULL represents an unknown value, and {expr}/0 is certainly an unknown value as well, the value would be the most appropriate.
If you then need to represent the NULL value in a particular way, you can wrap the whole expression in a further ISNULL.
In addition, you can use CASE to check zero values statement:
select (
(((57151130.0000000000)+(57612530.0000000000))/2)
/
CASE WHEN((12548020.0000000000)-(34321580.0000000000)+(21773560.0000000000)) = 0 THEN NULL
ELSE ((12548020.0000000000)-(34321580.0000000000)+(21773560.0000000000))
END
)*366

Why am I getting results that don't match the first WHERE clause?

WHERE [SOTR_CUST_CODE] = 'O004'
AND [SOTD_STRC_CODE] LIKE 'PC%'
OR [SOTD_STRC_CODE] LIKE 'PD%'
This returns records of customers that are not 'O004', and I'm not sure why. Is there also a better way to search for a string that could start with 2 different sets of characters without using the LIKE function twice?
Using SQL Server 2012
You need to use parentheses in your clause. Without parentheses, it means:
(A and B) OR C
Therefore you will get all records matching condition C regardless of condition A or B.
I know it already has very good answer (thanks to Laposhasu Acsa), but wanted to clarify for future readers:
Below code (without parentheses) is the same as (A and B) or C
WHERE [SOTR_CUST_CODE] = 'O004'
AND [SOTD_STRC_CODE] LIKE 'PC%'
OR [SOTD_STRC_CODE] LIKE 'PD%'
First solution is to use parentheses:
WHERE [SOTR_CUST_CODE] = 'O004'
AND ([SOTD_STRC_CODE] LIKE 'PC%'
OR [SOTD_STRC_CODE] LIKE 'PD%')
Second solution, which suits this particular case is:
WHERE [SOTR_CUST_CODE] = 'O004'
AND [SOTD_STRC_CODE] LIKE 'P[CD]%'

Oracle wildcard not matching? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
I am querying part numbers from an Oracle (JDE) database. If I use the clause WHERE Item LIKE 'AS-%', it correctly returns all the items that begin with 'AS-'. However, when I try to narrow that set by instead using the clause WHERE Item LIKE 'AS-%A' in order to find all parts matching the pattern and ending with an 'A', I get no results, even though they do exist!
What gives?
When you think that your query is misidentifying rows based on your understanding of the rows' values, examine the values using the DUMP() function.
This will tell you the exact contents of the cell, including any characters that you cannot see on the display.
I doubt if there is some space or non printable character present at the end of column values.
'AS-%A' must work if value actualy start with AS- and ends with A
To check, try to query using trim(Item) like 'AS-%A'
Perhaps some control characters at end of the data that you cannot see. Try using regexp_like:
with x as (
select 'AS-123B' as col from dual
UNION
select 'AS-456A' as col from dual
UNION
select 'AS-789A' || chr(0) as col from dual
)
select * from x
where regexp_like (col, 'AS-(.*)A[[:cntrl:]]?')
Output:
COL
AS-456A
AS-789A