ILIKE and Subquery Issue - sql

am struggling in ilike operation in pgSQL
select * from gtab47 where areaname ilike '(select place from gcompany where companyid=3)%'
how to correct it ?

There are a couple of things wrong here.
Subqueries aren't quoted and you must use || to concatenate strings, so you probably want to write something like:
select *
from gtab47
where areaname ilike (select place || '%' from gcompany where companyid=3)
Note that this query is incorrect unless companyid is UNIQUE or a PRIMARY KEY, since subqueries used in expressions must return at most one row.
If it's not unique or a primary key, you'll need to rephrase the query to use a join, or to use LIKE ANY using a subquery with array_agg.

Related

SQL: finding similar rows to other same table in special column

I am using SQLITE for running this query:
SELECT * FROM phrases1, phrases2 WHERE phrases1.word LIKE ('%' +phrases2.word+ '%')
but not works.
two tables phrases1, phrases2 are same and have column name word and I want to filter the first table by rows that word column is similar to the word column of second table . while this works:
SELECT * FROM phrases1, phrases2 WHERE phrases1.word LIKE phrases2.word
but I want to use wildcards.
The SQLite operator for string concatenation is || not +:
SELECT * FROM phrases1, phrases2
WHERE phrases1.word LIKE '%' || phrases2.word || '%'
Also I don't know what the effect of having parentheses around your LIKE expression would be, but you don't need them there. But you should really write your query using explicit joins, better yet use aliases too:
SELECT *
FROM phrases1 p1
INNER JOIN phrases2 p2
ON p1.word LIKE '%' || p2.word || '%'

How to use multiple values with like in sql

select * from user_table where name in ('123%','test%','dummy%')
How to ensure that this where clause is not an exact match, but a like condition?
In Oracle you can use regexp_like as follows:
select *
from user_table
where regexp_like (name, '^(123|test|dummy)')
The caret (^) requires that the match is at the start of name, and the pipe | acts as an OR.
Be careful though, because with regular expressions you almost certainly lose the benefit of an index that might exist on name.
Use like this,
select *
from user_table
where name LIKE '123%'
OR name LIKE 'test%'
OR name Like 'dummy%';
another option in MySQL
select * from user_table where name REGEXP '^123|^test|^dummy';
To not lose indexed access to rows in Oracle a table collection expression can be used:
SELECT
*
FROM
user_table
JOIN (SELECT column_value filter
FROM table(sys.odcivarchar2list('dummy%', '123%', 'test%'))
) ON user_table.name LIKE filter
The filter expressions must be distinct otherwise you get the same rows from user_table multiple times.

"NOT IN" subquery with a leading wildcard

I have two tables:
Table tablefoo contains a column fulldata.
Table tablebar contains a column partialdata.
I want find a list of tablefoo.fulldata that do NOT have partial matches in tablebar.partialdata.
The following provides a list of tablefoo.fulldata with partial matches in tablebar, but I want the negative of this.
select fulldata from tablefoo
where fulldata like any (select '%' || partialdata from tablebar);
This lists every record in partialdata:
select fulldata from tablefoow
where partialdata not in (select '%' || partialdata from tablebar);
Any idea how to get only the results tablefoo.fulldata that do not contain matches to a leading wildcarded tablebar.partialdata?
I found this link: PostgreSQL 'NOT IN' and subquery which seems like it's headed down the right path, but I'm not getting it to work with the wildcard.
Sure, I could write a script to pull this out of psql and do the comparisons, but it would be much nicer to handle this all as part of the query.
SELECT fulldata
FROM tablefoo f
WHERE NOT EXISTS (
SELECT 1
FROM tablebar b
WHERE f.fulldata LIKE ('%' || b.partialdata)
);

postgresql NOT ILIKE clause does not include null string values

Here's the setup on Postgresql 9.2.4:
CREATE TABLE table (
id integer NOT NULL,
some_text text
);
Now we enter one record, with a null or empty string for some_text, so that when we query:
SELECT * FROM table WHERE some_text IS NULL;
I get the entry back. So far so good.
However, when I query:
SELECT * FROM table WHERE some_text NOT ILIKE "%anything%';
I find that nothing was returned. Why is that? I expect a null or empty string to be "not like anything".
In SQL, NULL is not equal to anything. Nor is it unequal to anything.
In other words, if I don't tell you my middle name, and you don't tell me your middle name, how can we know if our two middle names are the same name or different names? We can't know.
This often trips people up in SQL, because it's "tri-value logic." An expression can be TRUE, FALSE, or UNKNOWN. Those of us familiar with boolean algebra know that NOT TRUE is FALSE, and NOT FALSE is TRUE.
But the tricky part is that NOT UNKNOWN is still UNKNOWN.
So the solution for you is either always store a non-null string in your column, or else use an expression to account for tri-value logic:
SELECT * FROM table WHERE some_text NOT ILIKE "%anything%' OR some_text IS NULL;
Or:
SELECT * FROM table WHERE COALESCE(some_text, '') NOT ILIKE '%anything%';
PostgreSQL also supports a null-safe equality operator:
SELECT * FROM table WHERE some_text IS DISTINCT FROM 'anything';
But unfortunately, this works only for equality, not for LIKE/ILIKE with patterns and wildcards.
You may use COALESCE to achieve your goal, like
SELECT * FROM table WHERE COALESCE(some_text,'') NOT ILIKE "%anything%';

SQL: Correctly identify and correct(if possible) names in database

I have a large database of names, and I'm hoping to identify incorrect capitalization.
Right now I'm using the following...
SELECT *
FROM myTable
WHERE LastName LIKE '%Mcd%' COLLATE SQL_Latin1_General_Cp1_CS_AS
Now of course this is inefficent because I have to run/edit this over and over for different cases. My thinking is find a list of name cases that would provide possible problems, and do
LIKE IN ('case1','case2','case3','case4', ...)
if that's possible. Is there another way that I'm not thinking of?
Other cases I'm thinking I'll have to check are abbreviations (%.%), hypens (%-%), and apostrophes (%'%).
You could use
SELECT *
FROM myTable
WHERE LastName LIKE '%Mcd%' or LastName LIKE '%Foo%'
Or
WITH T(Word) AS
(
SELECT 'Mcd' UNION ALL
SELECT 'Foo'
)
SELECT *
FROM myTable
JOIN T ON LastName LIKE '%' + Word + '%'
To avoid needing to scan myTable multiple times.
To avoid processing the string multiple times you could use CLR and Regular Expressions.