I am not able to make this out: Between eliminates use of >= and <=
...but when i tried this query:
SELECT *
FROM names
WHERE name >= 'Ankit'
AND name <= 'P'
...it gives output:
name
------
Ankit
Mac
Bob
When I tried:
SELECT *
FROM names
WHERE name BETWEEN 'Ankit' AND 'P'
...it gives output:
name
------
Ankit
Can you explain this why?
First, Oracle VARCHAR2 type is case sensitive.
Second, check that you do not have spaces in the beginning of name like this:
" Bob"
" Mac"
Use trim function to check if this causes the problem:
SELECT *
FROM names
WHERE trim(name) BETWEEN 'Ankit' AND 'P'
If this does not help, check that language and sort order are correct for your database.
Edit:
Since above advice did not solve your problem, you could try following:
Maybe you have some other non-printable characters in field. Use Oracle DUMP function to check:
SELECT DUMP(name), name FROM names
You should get something like this:
Typ=1 Len=3: 66,111,98 Bob
...
Verify that Len is correct length.
Check NLS parameters so that they are not inadvertently changed to something that does not work for your database:
SELECT * FROM NLS_SESSION_PARAMETERS
SELECT * FROM NLS_DATABASE_PARAMETERS
SELECT * FROM NLS_INSTANCE_PARAMETERS
Check results of these three queries and verify that parameters on sort, language and character set are correct.
I'm quite certain this has nothing to do with your syntax and everything to do with your DB setup. I've recreated your test scenario and, like others, have no problem with either query returning the results you expect. Did you check your NLS_SESSION_PARAMETERS as mentioned earlier?
SQL code is case insensitive.
String values and string comparisons are case sensitive.
See for yourself:
SELECT CASE WHEN 'a' = 'A' THEN 'string comparison is case insensitive'
WHEN 'a' <> 'A' THEN 'string comparison is case sensitive'
END
FROM dual;
You seem to have used a lowercase 'p' in the top query and an uppercase 'P' in the second. Was this intentional?
SELECT *
FROM names
WHERE name BETWEEN 'Ankit' AND 'P'
also should return all three rows - I just verified that it does so using your example. Are you sure that you made the test correctly? Maybe you inserted data in other session and didn't commit additional rows?
Nut 100% sure about it, but as it's only 3 rows, you could try it:
SELECT *
FROM names
WHERE (name BETWEEN "Ankit" AND "P")
OR (name BETWEEN "ankit" AND "p")
Related
I have a table with about 200 million records. One of the columns is defined as varchar(100) and it's included in a full text index. Most of the values are numeric. Only few are not numeric.
The problem is that it's not working well. For example if a row contains the value '123456789' and i look for '567', it's not returning this row. It will only return rows where the value is exactly '567'.
What am I doing wrong?
sql server 2012.
Thanks.
Full text search doesn't support leading wildcards
In my setup, these return the same
SELECT *
FROM [dbo].[somelogtable]
where CONTAINS (logmessage, N'28400')
SELECT *
FROM [dbo].[somelogtable]
where CONTAINS (logmessage, N'"2840*"')
This gives zero rows
SELECT *
FROM [dbo].[somelogtable]
where CONTAINS (logmessage, N'"*840*"')
You'll have to use LIKE or some fancy trigram approach
The problem is probably that you are using a wrong tool since Full-text queries perform linguistic searches and it seems like you want to use simple "like" condition.
If you want to get a solution to your needs then you can post DDL+DML+'desired result'
You can do this:
....your_query.... LIKE '567%' ;
This will return all the rows that have a number 567 in the beginning, end or in between somewhere.
99% You're missing % after and before the string you search in the LIKE clause.
es:
SELECT * FROM t WHERE att LIKE '66'
is the same as as using WHERE att = '66'
if you write:
SELECT * FROM t WHERE att LIKE '%66%'
will return you all the lines containing 2 'sixes' one after other
I am using PhpMysql and this simple query yields an empty result ("MySQL returned an empty result set").
Here is the query: SELECT * FROM TABLE 2 WHERE prenom LIKE '%Scott%'
My table has a row called prenomand there is a 'Scott' value. I have tried with other first names (which I know are in the database) and it does not work either.
The strange thing is that when I use the wildcards between One letter only i.e: SELECT * FROM TABLE 2 WHERE prenom LIKE '%S%' it works..
I need help please!
Ok so the pb was that due to the collation type instead of SCOTT, the file was encoded with spaces S C O T T. I had to reformat the file in utf8 to fix this!
I'm using Alpha Anywhere to take a SQL query that my company uses to create a grid.
The query is as follows:
SELECT t.name,cat.description,i.item_num,i.type_of_unit,i.brand,i.pack,i.description2
FROM cim i, tname t, cim cat
WHERE 'P'||i.price_book_code=t.nameid and i.price_book_group=cat.item_num and i.category!=95 and
i.buyer_num!=8 and cat.warehouse_num=0 and i.broken_case != 'Y' and i.item_num not in (select
item_num from proprietary_items)
ORDER BY t.name,cat.description,i.description2, type_of_unit;
In the Where clause, 'P' is concatenated to i.price_book_code to equal t.nameid because all those values have a P at the beginning.
This query works fine in sql-developer, however alpha anywhere will not run it. It claims invalid token at the 'P' level. Apparently this type of concatenation is not compatible to portable SQL. Is there any other way I can concatenate and compare?
Thank you,
Howard
The CONCAT function should work. Here's an example of using it in the WHERE clause:
SELECT *
FROM dual
WHERE CONCAT('Foo','Bar') = 'FooBar';
I have stored values in my database that look like 5XXXXXX, where X can be any digit. In other words, I need to match incoming SQL query strings like 5349878.
Does anyone have an idea how to do it?
I have different cases like XXXX7XX for example, so it has to be generic. I don't care about representing the pattern in a different way inside the SQL Server.
I'm working with c# in .NET.
You can write queries like this in SQL Server:
--each [0-9] matches a single digit, this would match 5xx
SELECT * FROM YourTable WHERE SomeField LIKE '5[0-9][0-9]'
stored value in DB is: 5XXXXXX [where x can be any digit]
You don't mention data types - if numeric, you'll likely have to use CAST/CONVERT to change the data type to [n]varchar.
Use:
WHERE CHARINDEX(column, '5') = 1
AND CHARINDEX(column, '.') = 0 --to stop decimals if needed
AND ISNUMERIC(column) = 1
References:
CHARINDEX
ISNUMERIC
i have also different cases like XXXX7XX for example, so it has to be generic.
Use:
WHERE PATINDEX('%7%', column) = 5
AND CHARINDEX(column, '.') = 0 --to stop decimals if needed
AND ISNUMERIC(column) = 1
References:
PATINDEX
Regex Support
SQL Server 2000+ supports regex, but the catch is you have to create the UDF function in CLR before you have the ability. There are numerous articles providing example code if you google them. Once you have that in place, you can use:
5\d{6} for your first example
\d{4}7\d{2} for your second example
For more info on regular expressions, I highly recommend this website.
Try this
select * from mytable
where p1 not like '%[^0-9]%' and substring(p1,1,1)='5'
Of course, you'll need to adjust the substring value, but the rest should work...
In order to match a digit, you can use [0-9].
So you could use 5[0-9][0-9][0-9][0-9][0-9][0-9] and [0-9][0-9][0-9][0-9]7[0-9][0-9][0-9]. I do this a lot for zip codes.
SQL Wildcards are enough for this purpose. Follow this link: http://www.w3schools.com/SQL/sql_wildcards.asp
you need to use a query like this:
select * from mytable where msisdn like '%7%'
or
select * from mytable where msisdn like '56655%'
I need to add the ability for users of my software to select records by character ranges.
How can I write a query that returns all widgets from a table whose name falls in the range Ba-Bi for example?
Currently I'm using greater than and less than operators, so the above example would become:
select * from widget
where name >= 'ba' and name < 'bj'
Notice how I have "incremented" the last character of the upper bound from i to j so that "bike" would not be left out.
Is there a generic way to find the next character after a given character based on the field's collation or would it be safer to create a second condition?
select * from widget
where name >= 'ba'
and (name < 'bi' or name like 'bi%')
My application needs to support localization. How sensitive is this kind of query to different character sets?
I also need to support both MSSQL and Oracle. What are my options for ensuring that character casing is ignored no matter what language appears in the data?
Let's skip directly to localization. Would you say "aa" >= "ba" ? Probably not, but that is where it sorts in Sweden. Also, you simply can't assume that you can ignore casing in any language. Casing is explicitly language-dependent, with the most common example being Turkish: uppercase i is İ. Lowercase I is ı.
Now, your SQL DB defines the result of <, == etc by a "collation order". This is definitely language specific. So, you should explicitly control this, for every query. A Turkish collation order will put those i's where they belong (in Turkish). You can't rely on the default collation.
As for the "increment part", don't bother. Stick to >= and <=.
For MSSQL see this thread: http://bytes.com/forum/thread483570.html .
For Oracle, it depends on your Oracle version, as Oracle 10 now supports regex(p) like queries: http://www.psoug.org/reference/regexp.html (search for regexp_like ) and see this article: http://www.oracle.com/technology/oramag/webcolumns/2003/techarticles/rischert_regexp_pt1.html
HTH
Frustratingly, the Oracle substring function is SUBSTR(), whilst it SQL-Server it's SUBSTRING().
You could write a simple wrapper around one or both of them so that they share the same function name + prototype.
Then you can just use
MY_SUBSTRING(name, 2) >= 'ba' AND MY_SUBSTRING(name, 2) <= 'bi'
or similar.
You could use this...
select * from widget
where name Like 'b[a-i]%'
This will match any row where the name starts with b, the second character is in the range a to i, and any other characters follow.
I think that I'd go with something simple like appending a high-sorting string to the end of the upper bound. Something like:
select * from widgetwhere name >= 'ba' and name <= 'bi'||'~'
I'm not sure that would survive EBCDIC conversion though
You could also do it like this:
select * from widget
where left(name, 2) between 'ba' and 'bi'
If your criteria length changes (as you seemed to indicate in a comment you left), the query would need to have the length as an input also:
declare #CriteriaLength int
set #CriteriaLength = 4
select * from widget
where left(name, #CriteriaLength) between 'baaa' and 'bike'