Query table by string matching without using LIKE? - sql

How can I query a table where first name starts with 'N' and last name starts with 'K' without using like?

Try something like the following:
SELECT * FROM mytable
WHERE SUBSTR(firstName, 1, 1) = 'N'
AND SUBSTR(lastName, 1, 1) = 'K';

you might try with > and < operators
e.g.:
WHERE NAME >= 'N' AND NAME < 'O'
but I don't guarantee you get each and every letter you would expect (especially with accentuated characters if any)
Scal

What about regular Expression ?
select * from table1 where regexp_like ( firstName, '^N*');
select * from table1 where regexp_like ( lastName, '^K*');

Related

Is first character of varchar a string?

How can I achieve the below to show all rows where the first character of the ClientNumber is not a letter of the alphabet?
select * from Table
where Left(ClientNumber,1) <> A to Z
You can simply do:
where left(clientNumber, 1) < 'A' or left(clientNumber, 1) > 'Z'
or:
where left(clientNumber, 1) not between 'A' and 'Z'
Do note, however, that the comparison will be tricky because of character case. Assuming 1-byte characters, you might want:
where ascii(left(clientNumber, 1)) not between ascii('A') and ascii('Z')
EDIT:
If I wanted to use an index:
where clientNumber < 'A' or clientNumber > 'Z['
However, I'm not so sure an index is really useful in this case.
You can use NOT LIKE:
SELECT *
FROM Table
WHERE ClientNumber NOT LIKE '[A-Za-z]%'
Try it like this...
SELECT
*
FROM
dbo.MyTable mt
WHERE
mt.ClientNumber LIKE '[^a-Z]%'

NVL Column and NULL

I have rows as shown below
ProductId ProductName ProductDesc ProductLoc
101 Camel Pencil B-10
102 Parker Pen
103 Mirado Pen C-10
When I execute the following SQL query
SELECT *
FROM tablename
WHERE productloc = NVL ('', productloc)
It gives me the 1st and 3rd row, what I would like to achieve is if productloc is null in where condition of the SQL, then I should get all three rows.
How can I get the desired output.
select * from tablename;
Is what you need in that case because your where gives no effect. You compare column with itself.
If you want to filter and include nulls you can do (but probably replace one productloc with some value:
select * from tablename where productloc = productloc or productloc is null;
Or:
select * from tablename where nvl(productloc, 'SOME_UNIQUE_VAL') = nvl(productloc, 'SOME_UNIQUE_VAL');
and also replace one of productloc by some value.
Try something like :
SELECT *
FROM tablename
WHERE nvl(productloc,'zzz') = (case when productloc is null then 'zzz' else productloc end )
Here zzz is some dummy value, which otherwise should not be present as value in particular column.
I suppose three different solutions:
If you want all rows (with productloc null and valued) you can write the following query:
SELECT *
FROM tablename
Without WHERE clause.
If you want extract all rows with productloc has a specified value or is null, so you can write the following query:
SELECT *
FROM tablename
WHERE productloc IS NULL OR productloc = YOURVARIABLE
or (the last, without use OR condition)
SELECT *
FROM tablename
WHERE NVL(productloc, YOURVARIABLE) = YOURVARIABLE
I assume you are using Oracle. In Oracle "NULL" is not a value and because of it any compare function will return false.
I recomend:
SELECT *
FROM tablename
WHERE (productloc = productloc OR productloc IS NULL)
Hope it helps,
Sérgio

Is it possible to use Informix NVL with two subqueries?

I want to get a parameter. The priority for getting that parameter is that I have to look for it in Table1, but if it doesn't exist there, I have to look for it in Table2. If not, so that parameter is null (this situation should not happen, but, well, there is always an edge case).
I wanted to try something like this:
SELECT NVL(
SELECT paramValue from Table1
where paramName = "paramName" and Id = "id",
SELECT paramValue from Table2
where paramName = "paramName" and Id = "id")
But it gives me a syntax error.
Is there any way of doing something like this?
Enclose the sub-queries in their own set of parentheses, like this:
SELECT NVL((SELECT Atomic_Number FROM Elements WHERE Name = 'Tungsten'),
(SELECT Atomic_Number FROM Elements WHERE Name = 'Helium'))
FROM sysmaster:informix.sysdual;
74
SELECT NVL((SELECT Atomic_Number FROM Elements WHERE Name = 'Wunderkind'),
(SELECT Atomic_Number FROM Elements WHERE Name = 'Helium'))
FROM sysmaster:informix.sysdual;
2
SELECT NVL((SELECT Atomic_Number FROM Elements WHERE Name = 'Wunderkind'),
(SELECT Atomic_Number FROM Elements WHERE Name = 'Helios'))
FROM sysmaster:informix.sysdual;
 
The last query generated a NULL (empty line) as output, which is mimicked by a non-breaking space on the last line.
Granted, I'm not selecting from two tables; that's immaterial to the syntax, and the sub-queries would work on two separate tables as well as on one table.
Tested with Informix 12.10.FC6 and CSDK 4.10.FC6 on Mac OS X 10.11.5.
There's another way:
SELECT * FROM (
SELECT paramValue from Table1
where paramName = "paramName" and Id = "id"
union all
SELECT paramValue from Table2
where paramName = "paramName" and Id = "id"
) x
LIMIT 1
Which is IMHO easier to read.

sql server using SUBSTRING with LIKE operator returns no results

I created this CTE that returns first and last names from 2 different tables. I would like to use the CTE to identify all of the records that have the same last names and the first name of one column starts with the same first letter of another column.
This is an example of the results of the CTE. I want the SELECT using the CTE to return only the highlighted results:
;WITH CTE AS
(
SELECT AD.FirstName AS AD_FirstName, AD.LastName AS AD_LastName, NotInAD.FirstName As NotInAD_FirstName, NotInAD.LastName As NotInAD_LastName
FROM PagingToolActiveDirectoryUsers AD JOIN
(
SELECT FirstName, LastName
FROM #PagingUsersParseName
EXCEPT
SELECT D.FirstName, D.LastName
FROM PagingToolActiveDirectoryUsers D
WHERE D.FirstName <> D.LastName AND D.LastName <> D.LoginName
AND D.LoginName LIKE '%[0-9]%[0-9]%'
) AS NotInAD ON NotInAD.LastName = AD.LastName
)
SELECT *
FROM CTE
WHERE (AD_LastName = NotInAD_LastName) AND (AD_FirstName LIKE ('''' + SUBSTRING(NotInAD_FirstName, 1, 1) + '%'''))
ORDER BY AD_LastName, AD_FirstName;
The result of this query returns no rows.
What am I doing wrong?
Thanks.
You're enclosing the string to be searched for with single-quotes, but it doesn't appear that the data in AD_FirstName has those single-quotes embedded in it. I suggest you replace the first line of the WHERE clause with
WHERE (AD_LastName = NotInAD_LastName) AND (AD_FirstName LIKE (SUBSTRING(NotInAD_FirstName, 1, 1) + '%'))
Best of luck.

T-SQL Comma delimited value from resultset to in clause in Subquery

I have an issue where in my data I will have a record returned where a column value will look like
-- query
Select col1 from myTable where id = 23
-- result of col1
111, 104, 34, 45
I want to feed these values to an in clause. So far I have tried:
-- Query 2 -- try 1
Select * from mytableTwo
where myfield in (
SELECT col1
from myTable where id = 23)
-- Query 2 -- try 2
Select * from mytableTwo
where myfield in (
SELECT '''' +
Replace(col1, ',', ''',''') + ''''
from myTable where id = 23)
-- query 2 test -- This works and will return data, so I verify here that data exists
Select * from mytableTwo
where myfield in ('111', '104', '34', '45')
Why aren't query 2 try 1 or 2 working?
You don't want an in clause. You want to use like:
select *
from myTableTwo t2
where exists (select 1
from myTable t
where id = 23 and
', '+t.col1+', ' like '%, '+t2.myfield+', %'
);
This uses like for the comparison in the list. It uses a subquery for the value. You could also phrase this as a join by doing:
select t2.*
from myTableTwo t2 join
myTable t
on t.id = 23 and
', '+t.col1+', ' like '%, '+t2.myfield+', %';
However, this could multiply the number of rows in the output if there is more than one row with id = 23 in myTable.
If you observe closely, Query 2 -- try 1 & Query 2 -- try 2 are considered as single value.
like this :
WHERE myfield in ('111, 104, 34, 45')
which is not same as :
WHERE myfield in ('111', '104', '34', '45')
So, If you intend to filter myTable rows from MyTableTwo, you need to extract the values of fields column data to a table variable/table valued function and filter the data.
I have created a table valued function which takes comma seperated string and returns a table value.
you can refer here T-SQL : Comma separated values to table
Final code to filter the data :
DECLARE #filteredIds VARCHAR(100)
-- Get the filter data
SELECT #filteredIds = col1
FROM myTable WHERE id = 23
-- TODO : Get the script for [dbo].[GetDelimitedStringToTable]
-- from the given link and execute before this
SELECT *
FROM mytableTwo T
CROSS APPLY [dbo].[GetDelimitedStringToTable] ( #filteredIds, ',') F
WHERE T.myfield = F.Value
Please let me know If this helps you!
I suppose col is a character type, whose result would be like like '111, 104, 34, 45'. If this is your situation, it's not the best of the world (denormalized database), but you can still relate these tables by using character operators like LIKE or CHARINDEX. The only gotcha is to convert the numeric column to character -- the default conversion between character and numeric is numeric and it will cause a conversion error.
Since #Gordon, responded using LIKE, I present a solution using CHARINDEX:
SELECT *
FROM mytableTwo tb2
WHERE EXISTS (
SELECT 'x'
FROM myTable tb1
WHERE tb1.id = 23
AND CHARINDEX(CONVERT(VARCHAR(20), tb2.myfield), tb1.col1) > 0
)