Two Where conditions on same column - sql

There are several status an the status table. I want query like that.
select * from command where status <> 's' and status<> 'sc'
But query retrieve data with 'Status' S.
What was the issue on that?

Is the status in the DB S or s?
Try
select * from command where lower(status) NOT IN ('s', 'sc')

Just try it.. No need to check lower or caps. It searches all letter (not case sensitive).
select * from command where status NOT IN ('s', 'sc')
If you want to add condition with case sensitive, then you have to use like this..
select * from command where status COLLATE Latin1_General_CS_AS NOT IN ('s', 'sc')

The checks Col <> 's' depends on the collation of the columns. If the collation is case insensitive, then 'S' = 's' and your checks will not return S. If your collation is case sensitive which I believe is the case, will return S.
For example note the following two collations Latin1_General_CI_AS_KS_WS and Latin1_General_CS_AS_KS_WS. Note the difference in case CI and CS.
SELECT 'S' WHERE 'S' <> 's' COLLATE Latin1_General_CI_AS_KS_WS
Does not return anything
SELECT 'S' WHERE 'S' <> 's' COLLATE Latin1_General_CS_AS_KS_WS
Returns S
Coming back to your query. If this case insensitive check is a one time thing you can either as suggested by other answers do a UPPER(Col) / LOWER(Col) or use COL COLLATE Latin1_General_CI_AS_KS_WS.
If all comparisons should be case insensitive, I would suggest changing the collation of the column itself.

Related

Is there a CASE statement to apply to several columns to have a like output value changed to another (but different) like value?

I have several columns that read "Not Specified". I would like them to be blank instead.
Is there a better way to apply a case statement to my ENTIRE query rather than each line, if I'm looking to change the same value in different columns? Currently my query looks like this (plus several columns):
SELECT
[user_name]
,[employee_number]
,CASE [veteran_status] WHEN 'not specified' THEN ''
ELSE veteran_status
END AS veteran_status
,CASE [ethnic_origin] WHEN 'not specified' THEN ''
ELSE ethnic_origin
END AS ethnic_origin
,CASE [gender] WHEN 'not specified' THEN ''
ELSE gender
END AS gender
FROM table.HR
I am getting the correct output with the case statements, but looking to see if there's a more efficient way to apply CASE to a mass amount.
Well you can combine the UNPIVOT and PIVOT operators like so:
with t1 as (
select user_name
, employee_number
, col
, nullif(value,'not specified') value
from HR unpivot(value for col in (veteran_status, ethnic_origin, gender)) as x
)
select *
from t1
pivot (max(value) for col in (veteran_status, ethnic_origin, gender)) x;
If your columns aren't of the same data type, you might need to precondition them by casting them all to the same data type:
with t0 as (
select user_name
, employee_number
, cast(veteran_status as varchar(30)) veteran_status
, cast(ethnic_origin as varchar(30)) ethnic_origin
, cast(gender as varchar(30)) gender
from HR
), t1 as (... from t1 ...)
...
However, this may be a LOT of work for something easily achievable by more conventional means.
There is no way using which you can apply one principle (logic) to multiple / all columns of a select statement without putting them for each column.
What you can do though is write alternatives that are more concise than CASE statement. From your query style, I guess you are using MS SQL server, here is one alternative for MS SQL Server
SELECT
[user_name]
,[employee_number]
,iif([veteran_status] = 'not specified', '', [veteran_status]) veteran_status
,iif([ethnic_origin] = 'not specified', '', [ethnic_origin]) ethnic_origin
,iif([gender] = 'not specified', '', [gender]) gender
FROM table.HR
For Oracle there is a similar function called decode, Mysql equivalent is called if
That said, CASE is standard ANSII SQL, available in all databases. Choice is yours.
The following solution will work when you also want to resolve NULLs with the same value. You will still need to add this to each column that is referenced, but it uses less code & reduces redundancy overall.
ISNULL(NULLIF([veteran_status], ‘not specified’), ‘’) AS [veteran_status]
You could join the table to itself, excluding the 'not specified' columns. There isnt a huge gain, however, its an alternative perspective.
SELECT
user_name
,employee_number
,veteran_status
,ethnic_origin
,gender
FROM table.HR hr
LEFT JOIN table.HR hrvs ON hrvs.employee_number = hr.employee_number AND hrvs.veteran_status <> 'not specified'
LEFT JOIN table.HR hreo ON hreo.employee_number = hr.employee_number AND hreo.ethnic_origin <> 'not specified'
LEFT JOIN table.HR hrge ON hrge.employee_number = hr.employee_number AND hrge.gender <> 'not specified'

how to display names who's initial are starting from K,B,A in sql?

How to display names who's initial are starting from K,B,A in sql? The result should comes like eg:-Keven,karun,Bean,Brown,Aron,Abiel
Select name_field
From yourTable
Where upper( substr( name_field, 1, 1)) in ('K', 'B', 'A')
You could use REGEX_LIKE to perform this operation.
What it does is it performs a regular expression matching instead of a simple pattern matching.
SELECT name FROM users WHERE name LIKE 'k%' OR name LIKE 'b%' OR name LIKE 'a%' COLLATE utf8_general_ci
% matches any string, so the above query will match any name starting with b, a or k. the COLLATE rule is there to tell the query that it is case insensitive.
Use REGEXP_LIKE as shown below. It can match a regular expression, which is a better alternative in this case instead of using multiple like statements.
DBFiddle Demo
select name from
your_table t
where REGEXP_LIKE (name, '^[K|B|A]','i');
Regex ^[K|B|A] matches every word which starts with either K or B or A. i for case insensitive matching.

How to check for null/whitespace/NA values while selecting in SQL?

SELECT column_name1,column_name2,column_name3,column_name4 from table_name
How do i do multiple checks for all the coulmn_name?
for now i am checking for NULL to return "Empty String" using COALESCE.
SELECT
COALESCE(column_name1,'')as Column_name1,
COALESCE(column_name2,'')as Column_name2,
COALESCE(column_name3,'')as Column_name3,
COALESCE(column_name4,'')as Column_name4, from table_name
My requirement is to return "Empty String" where ever the values are NULL or WhiteSpaces or NA.
Thanks in advance.
One method uses case:
select (case when column_name1 is null or ltrim(rtrim(column_name1)) in ('NA', '') then ''
else column_name1
end)
CASE, ISNULL, COALESCE can all be used in combination as necessary.
If you are using the 2012 or later versions of SQL Server, there are 2 more options to choose from to simplify CASE statement:
1. IIF
2. CHOOSE
Check this link for more details
SELECT coalesce (nullif (rtrim(ltrim(column_name1)), 'N/A'), '')
AS column_name1
FROM table_name
Found an answer.. is this correct way?? i mean does this works exactly to the requirement?

SQL Server queries case sensitivity

I have this database:
abcDEF
ABCdef
abcdef
if I write: select * from MyTbl where A='ABCdef'
how to get: ABCdef
and how to get:
abcDEF
ABCdef
abcdef
Thanks in advance
forgot to write - sqlCE
You can make your query case sensitive by making use of the COLLATE keyword.
SELECT A
FROM MyTbl
WHERE A COLLATE Latin1_General_CS_AS = 'ABCdef'
If you have abcDEF, ABCdef, abcdef already in the database then it's already case sensitive or you have no constraint.
You'd have to add a COLLATE on both sides to make sure it's truly case sensitive (for a non case sensitive database) which will invalidate index usage
SELECT TheColumn
FROM MyTable
WHERE TheColumn COLLATE Latin1_General_CS_AS = 'ABCdef' COLLATE Latin1_General_CS_AS
What about accents too? Latin1_General_CS_AI, Latin1_General_Bin?
Try this just add binary keyword after where:
select * from MyTbl where binary A = 'ABCdef';
It's all about collation. Each one has a suffix (CI and CS, meaning Case Insensitive, and Case Sensitive).
http://www.databasejournal.com/features/mssql/article.php/10894_3302341_2/SQL-Server-and-Collation.htm
SQL is non-case-sensitive by default, so you will get all three items if doing a simple string comparison. To make it case-sensitive, you can cast the value of the field and your search value as varbinary:
SELECT * FROM MyTbl WHERE CAST(A AS varbinary(20)) = CAST('ABCdef' as varbinary(20))
The above assumes your varchar field is sized at 20. For nvarchar double it (thanks #ps2goat).

how to select * from tableA where columnA values don't start with letter 'F'

Can I have a SQL query to get the data from columna in tableA whose values don't start with 'f' ?
For example:
select * from tableA where columnA
where values don't start with letter 'F'.
For a MSSQL Scenario, you should be able to use the "NOT" operator in conjunction with the LIKE operator. So your SQL would look roughly like
select * from tableA where columnA NOT LIKE 'F%'
#Evan: the statement about SQL Server being case insensitive is actually not entirely true. Case sensitivity depends on collation. The server has a collation (chosen on install), a database has a collation (chosen on DB creation) and text columns have a collation (chosen when creating the column). When no collation is specified on DB creation, the server collation will be the default. When no collation specified on column creation it gets the same collation as the DB.
But in most cases, people (luckily) install their server using a case insensitive collation, such as Latin1_General_CI_AS. CI = case insensitive, AS = accent sensitive.
On SQL Server, if I needed to get both the small f and capital F, I would go for:
where columnA NOT LIKE 'F%' and columnA NOT LIKE 'f%'
PS: I'm adding this as "answer" because I don't see any option to comment on an existing answer - I'm still new here... If anyone has an explanation why I don't get this option, don't hesitate to contact me.
Regards, Valentino.
SELECT columnA
FROM tableA
WHERE SUBSTR(columnA,1,1) <> 'f'
If you need both 'f' and 'F':
SELECT columnA
FROM tableA
WHERE SUBSTR(columnA,1,1) NOT IN ('f','F')
Going off of Lerxst's example, some DBMSs will also let you do fun stuff like this:
SELECT columnA
FROM tableA
WHERE columnA NOT LIKE ALL ('f%','F%')
I like all of the ideas above, but I usually take a different approach.
SELECT *
FROM tableA
WHERE LEFT(columnA,1) <> 'F'
T-SQL really offers a million ways to skin a cat.
Searching for both F and f seems like way too much work
SELECT *
FROM tableA
WHERE upper(substr(columnA,1,1)) != 'F'
Or to quote my friend Ritchie - when searching in sql, trim it and then force it upper