Snowflake Where Clause Not Filtering? - sql

I am running this query in snowflake:
select *
from my_database.information_schema.tables
where
table_schema NOT LIKE '%information%';
When I look at the records, some of them have INFORMATION_SCHEMA as the table_schema.
Why is my filter not working?

LIKE is case sensitive, where-as ILIKE is case insensitive. And your two strings are different cases. So I suggest you swap to ILIKE
SELECT 'a' LIKE 'A' as "a_like_A", 'a' ILIKE 'A' as "a_ilike_A";
gives:
a_like_A a_ilike_A
FALSE TRUE

When I look at the records, some of them have INFORMATION_SCHEMA as the table_schema.
Identifiers
When an identifier is unquoted, it is stored and resolved in uppercase.
The issue is you are comparing uppercase vs lowercase string which are different.
where table_schema LIKE '%information%'; -- this comparison will not work
Other way to compare:
where table_schema LIKE UPPER('%information%');
It is worth noting that SHOW TABLES LIKE '<patern>' is case-insensitive by design, and will return a match for the following regardless of version used:
SHOW TABLES LIKE '%information%';
SHOW TABLES LIKE '%INFORMATION%';
SHOW TABLES LIKE '%Information%';

Related

PostgreSQL pattern match query does not work as expected [duplicate]

I looked around some and didn't find what I was after so here goes.
SELECT * FROM trees WHERE trees.`title` LIKE '%elm%'
This works fine, but not if the tree is named Elm or ELM etc...
How do I make SQL case insensitive for this wild-card search?
I'm using MySQL 5 and Apache.
I've always solved this using lower:
SELECT * FROM trees WHERE LOWER( trees.title ) LIKE '%elm%'
SELECT *
FROM trees
WHERE trees.`title` COLLATE UTF8_GENERAL_CI LIKE '%elm%'
Actually, if you add COLLATE UTF8_GENERAL_CI to your column's definition, you can just omit all these tricks: it will work automatically.
ALTER TABLE trees
MODIFY COLUMN title VARCHAR(…) CHARACTER
SET UTF8 COLLATE UTF8_GENERAL_CI.
This will also rebuild any indexes on this column so that they could be used for the queries without leading '%'
The case sensitivity is defined in the columns / tables / database collation settings. You can do the query under a specific collation in the following way:
SELECT *
FROM trees
WHERE trees.`title` LIKE '%elm%' COLLATE utf8_general_ci
for instance.
(Replace utf8_general_ci with whatever collation you find useful). The _ci stands for case insensitive.
This is the example of a simple LIKE query:
SELECT * FROM <table> WHERE <key> LIKE '%<searchpattern>%'
Now, case-insensitive using LOWER() func:
SELECT * FROM <table> WHERE LOWER(<key>) LIKE LOWER('%<searchpattern>%')
Simply use :
"SELECT * FROM `trees` WHERE LOWER(trees.`title`) LIKE '%elm%'";
Or Use
"SELECT * FROM `trees` WHERE LCASE(trees.`title`) LIKE '%elm%'";
Both functions works same
I'm doing something like that.
Getting the values in lowercase and MySQL does the rest
$string = $_GET['string'];
mysqli_query($con,"SELECT *
FROM table_name
WHERE LOWER(column_name)
LIKE LOWER('%$string%')");
And For MySQL PDO Alternative:
$string = $_GET['string'];
$q = "SELECT *
FROM table_name
WHERE LOWER(column_name)
LIKE LOWER(?);";
$query = $dbConnection->prepare($q);
$query->bindValue(1, "%$string%", PDO::PARAM_STR);
$query->execute();
use ILIKE
SELECT * FROM trees WHERE trees.`title` ILIKE '%elm%';
it worked for me !!
Non-binary string comparisons (including LIKE) are case insensitive by default in MySql:
https://dev.mysql.com/doc/refman/en/case-sensitivity.html
I think this query will do a case insensitive search:
SELECT * FROM trees WHERE trees.`title` ILIKE '%elm%';
You don't need to ALTER any table. Just use the following queries, prior to the actual SELECT query that you want to use the wildcard:
set names `utf8`;
SET COLLATION_CONNECTION=utf8_general_ci;
SET CHARACTER_SET_CLIENT=utf8;
SET CHARACTER_SET_RESULTS=utf8;
well in mysql 5.5 , like operator is insensitive...so if your vale is elm or ELM or Elm or eLM or any other , and you use like '%elm%' , it will list all the matching values.
I cant say about earlier versions of mysql.
If you go in Oracle , like work as case-sensitive , so if you type like '%elm%' , it will go only for this and ignore uppercases..
Strange , but this is how it is :)
SELECT name
FROM gallery
WHERE CONVERT(name USING utf8) LIKE _utf8 '%$q%'
GROUP BY name COLLATE utf8_general_ci LIMIT 5
You must set up proper encoding and collation for your tables.
Table encoding must reflect the actual data encoding. What is your data encoding?
To see table encoding, you can run a query SHOW CREATE TABLE tablename
When I want to develop insensitive case searchs, I always convert every string to lower case before do comparasion
I've always solved like this:
SELECT * FROM trees WHERE LOWER( trees.title ) LIKE LOWER('%elm%');
For example if you want to search name like Raja not raja, Royal not royal etc, add BINARY before column name in WHERE clause.
SELECT name FROM person_tbl
WHERE BINARY name LIKE "R%";

Why some of the results for SQL query containing certain alphabets are missing?

I have following table
When I run following query, it should have shown all instructor name containing 's' but it doesnot.
The query I've written:
SQL> SELECT instructor_name
2 FROM instructor
3 WHERE instructor_name LIKE '%s%';
The result is:
What is the problem here? Should not Balbir Silakar and Saurav Pangeni too must appear on the result?
's' and 'S' are two different things if your column has a case-sensitive collation.
Alas, Oracle does not provide a case-insensitive version of like (usually called ilike in other databases).
You could do:
where instructor_name like '%s%' or instructor_name like '%S%'
Or:
where lower(instructor_name) like '%s%'
Or, you can use regexp_like(); it takes a third argument that can be used to make the search case insensitive.
where regexp_like(instructor_name, 's', 'i')
I would not be surprised that the regex would be the fastest option out of the three.
As others have mentioned, s (chr(115)) and S (chr(83)) are two different things, and there is no s in 'Balbir Silakar' or 'Saurav Pangeni'.
From Oracle 12.2 you can use
where instructor_name collate binary_ci like '%s%';
You can additionally ignore accents with
where instructor_name collate binary_ai like '%s%';
Your database (by default I think) is case-sensitive, thus the LIKE matching mechanism is case-sensitive. Those names contain an upper-case S.
Here's a Q&A on how to make the search not case-sensitive. Perform a Case insensitive Like query in a case sensitive SQL Server database
For case insensitive check use regexp_like
where regexp_like(instructor_name , 's', 'i');

Behaviour of NOT LIKE with NULL values

I want to fetch all columns of a table except of columns of type serial. The closest query to this problem I was able to come up with this one:
SELECT column_name FROM information_schema.columns
WHERE table_name = 'table1' AND column_default NOT LIKE 'nextval%'
But the problem is its also excluding/filtering rows having empty values for column_default.I don't know why the behaviour of Postgres is like this. So I had to change my query to something like this:
SELECT column_name FROM information_schema.columns
WHERE table_name = 'table1'
AND ( column_default IS NULL OR column_default NOT LIKE 'nextval%')
Any better suggestions or rationale behind this are welcome.
About null
'anything' NOT LIKE null yields null, not true.
And only true qualifies for filter expressions in a WHERE clause.
Most functions return null on null input (there are exceptions). That's the nature of null in any proper RDBMS.
If you desire a single expression, you could use:
AND (column_default LIKE 'nextval%') IS NOT TRUE;
That's hardly shorter or faster, though. Details in the manual.
Proper query
Your query is still unreliable. A table name alone is not unique in a Postgres database, you need to specify the schema name in addition or rely on the current search_path to find the first match in it:
Related:
How does the search_path influence identifier resolution and the "current schema"
SELECT column_name
FROM information_schema.columns
WHERE table_name = 'hstore1'
AND table_schema = 'public' -- your schema!
AND (column_default IS NULL
OR column_default NOT LIKE 'nextval%');
Better, but still not bullet-proof. A column default starting with 'nextval' does not make a serial, yet. See:
Auto increment table column
To be sure, check whether the sequence in use is "owned" by the column with pg_get_serial_sequence(table_name, column_name).
I rarely use the information schema myself. Those slow, bloated views guarantee portability across major versions - and aim at portability to other standard-compliant RDBMS. But too much is incompatible anyway. Oracle does not even implement the information schema (as of 2015).
Also, useful Postgres-specific columns are missing in the information schema. For this case I might query the the system catalogs like this:
SELECT *
FROM pg_catalog.pg_attribute a
WHERE attrelid = 'table1'::regclass
AND NOT attisdropped -- no dropped (dead) columns
AND attnum > 0 -- no system columns
AND NOT EXISTS (
SELECT FROM pg_catalog.pg_attrdef d
WHERE (d.adrelid, d.adnum) = (a.attrelid, a.attnum)
AND d.adsrc LIKE 'nextval%'
AND pg_get_serial_sequence(a.attrelid::regclass::text, a.attname) <> ''
);
Faster and more reliable, but less portable.
The manual:
The catalog pg_attrdef stores column default values. The main
information about columns is stored in pg_attribute (see below). Only
columns that explicitly specify a default value (when the table is
created or the column is added) will have an entry here.
'table1'::regclass uses the search_path to resolve the name, which avoids ambiguity. You can schema-qualify the name to overrule: 'myschema.table1'::regclass.
Related:
Find the referenced table name using table, field and schema name
Get the default values of table columns in Postgres?
I think you can use :
SELECT column_name *FROM* information_schema.columns
WHERE table_name = 'table1'
AND ( nvl(column_default,0) *NOT LIKE* 'nextval%');

How can I search for numbers in a varchar column

I've got a simple nvarchar(25) column in an SQL database table. Most of the time, this field should contain alphanumeric text. However, due to operator error, there are many instances where it contains only a number. Can I do a simple search in SQL to identify these cases? That is, determine which rows in the table contain only digits in this column. As an extension, could I also search for those column values which contain only digits and a space and/or slash.
In other languages (eg. Perl, Java) a regular expression would resolve this quickly and easily. But I haven't been able to find the equivalent in SQL.
yes you can achive this by using isnumeric function available in sql sever
check more at this link : http://msdn.microsoft.com/en-us/library/aa933213(SQL.80).aspx
All the answers referred to the isnumeric function, but they are not correct, I've mentioned in a comment for all the answers the flaw in the answers. The correct solution is to use a regular expression in your where clause, which contains not like '%[^0-9]%', see the example below:
select column_name from table_name where column_name not like '%[^0-9]%'
select column_name from table_name where IsNumeric(column_name) <> 1
Numeric Only:
SELECT * FROM Table WHERE ISNUMERIC(Field) = 1
With Space:
SELECT * FROM Table WHERE Field LIKE '% %'
With Slash:
SELECT * FROM Table WHERE Field LIKE '%/%'
Combined:
SELECT * FROM Table WHERE ISNUMERIC(Field) = 1 OR Field LIKE '% %' OR Field LIKE '%/%'

What's the preferred way to return an empty table in SQL?

I know I can return an empty table using the following query :
select * from tbFoo where 1=2
but that code doesn't look nice to me.
Is there a 'standard' way of doing this?
If you're wondering why I want to do such a strange thing, it's because I can't name the datatables I return from a stored procedure, so I need empty placeholders.
Having just run both:
SELECT TOP 0 * FROM Table
and
SELECT * FROM Table WHERE 1=0
They produce exactly the same execution plan.
Most of the time I see 1=0 but yes thats pretty much the standard approach when you really have to. Although really having to is rare.
What you really need is information_schema, using it will allow you to find out the definition of a table.
You don't mention which database you are using, so here is a link about information_schema Support in MySQL, PostgreSQL (and MSSQL, Oracle, Etc)
An example from the site;
SELECT table_name, column_name, is_nullable, data_type, character_maximum_length
FROM INFORMATION_SCHEMA.Columns
WHERE table_name = 'employees'
In your case, all you need are the column names;
SELECT column_name
FROM INFORMATION_SCHEMA.Columns
WHERE table_name = 'employees'