SQL find '%' between %s - sql

I need to find (exclude in fact) any results that contain '%' sign, wherever in a string field. That would mean ... WHERE string LIKE '%%%'. Googling about escaping gave me the following ideas. The first throws syntax error, the second returns rows but there are records actually contain '%'.
1st:
SELECT * FROM table
WHERE string NOT LIKE '%!%%' ESCAPE '!'
///tried with different escape characters
2nd:
SELECT * FROM table
WHERE string NOT LIKE '%[%]%'
Trying on GCP BigQuery.

Try:
SELECT *
FROM table
WHERE string NOT LIKE '%!%%' {ESCAPE '!'}
With curly braces as shown in microsoft sql server docs

Or also:
WITH indata(s) AS (
SELECT 'not excluded'
UNION ALL SELECT '%excluded'
UNION ALL SELECT 'Ex%cluded'
UNION ALL SELECT 'Excluded%'
)
SELECT * FROM indata WHERE INSTR(s,'%') = 0;
-- out s
-- out --------------
-- out not excluded

find (exclude in fact) any results that contain '%'
Consider below simple approach
select *
from your_table
where not regexp_contains(string , '%')

Related

Sybase LIST function truncating results after 256 characters

I'm trying to aggregate a column of strings into one cell by concatenating them together and separating them with commas using syabase's LIST fuction. But the results get truncated after 256 characters. Does anyone know of a way to fix this or if there are any alternatives that would give me what I'm looking for.
For example, if I have a table myTable that looks like this:
myVal
-------------
'0000000001'
'0000000002'
'0000000003'
'0000000004'
'0000000005'
'0000000006'
'0000000007'
'0000000008'
'0000000009'
'0000000010'
'0000000011'
'0000000012'
'0000000013'
'0000000014'
'0000000015'
'0000000016'
'0000000017'
'0000000018'
'0000000019'
'0000000020'
'0000000021'
'0000000022'
'0000000023'
'0000000024'
'0000000025'
'0000000026'
'0000000027'
'0000000028'
'0000000029'
'0000000030'
then run the following query:
select list(myVal,',') as myResult from myTable
I get the following result
myResult
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
0000000001,0000000002,0000000003,0000000004,0000000005,0000000006,0000000007,0000000008,0000000009,0000000010,0000000011,0000000012,0000000013,0000000014,0000000015,0000000016,0000000017,0000000018,0000000019,0000000020,0000000021,0000000022,0000000023,000
Notice the result string gets truncated after 0000000023
Try this:
SELECT
LIST( CAST( myVal AS nvarchar(max) ), ',' )
FROM
myTable

Escaping single quotes in REDSHIFT SQL

I've lots of string values containing single quotes which I need to insert to a column in REDSHIFT table.
I used both /' and '' to escape the single quote in INSERT statement.
e.g.
INSERT INTO table_Temp
VALUES ('1234', 'O\'Niel'), ('3456', 'O\'Brien')
I also used '' instead of \' but it keeps giving me error that "VALUES list must of same length" i.e. no: of arguments for each record >2.
Can you let know how to have this issue resolved?
The standard in SQL is double single quotes:
INSERT INTO table_Temp (col1, col2) -- include the column names
VALUES ('1234', 'O''Niel'), ('3456', 'O''Brien');
You should also include the column names corresponding to the values being inserted. That is probably the cause of your second error.
You could use CHR(39) and concat the strings. Your name would look like below:
('O' || CHR(39)||'Brian')
I think it may depend on your environment. I'm using Periscope Data's redshift SQL editor, and \ worked as an escape character. '' and \\ did not work.
I was facing similar problem , I was needing send a kind of JSON structure to then decode it into my query but there was a program receiving my string and this program was escaping my escapes, so the query fails, finally I found this :
Put $$ in dollar-quoted string in PostgreSQL
mentioning quote_literal(42.5)
https://www.postgresql.org/docs/current/functions-string.html#FUNCTIONS-STRING-OTHER
This resolves my issue . an example
String is
'LocalTime={US/Central}; NumDays={1}; NumRows={3}; F_ID={[Apple, Orange, Bannana]}'
Select
Param, value , replace(quote_literal(replace(replace(Value,'[',''),']','')),',',quote_literal(',')) ValueList
FROM (
select
SPLIT_PART(split,'=',1) as Param,
replace( replace(SPLIT_PART(split,'=',2),'{',''),'}','') as Value
FROM
(
select
trim(split_part(freeform.txt, ';', number.n)) as split
from
( select
'LocalTime={US/Central}; NumDays={1}; NumRows={3}; F_ID={[Apple, Orange, Bannana]}' as txt
) freeform,
( select 1 as n union all
select 2 union all
select 3 union all
select 4 union all
select 5 union all
select 6 union all
select 7 union all
select 8 union all
select 9 union all
select 10
) number
where split <> ''
) as MY_TMP
) as valuePart
use \\' to escape '
s = s.replace("'", "\\'")

SQL special group by on list of strings ending with *

I would like to perform a "special group by" on strings with SQL language, some ending with "*". I use postgresql.
I can not clearly formulate this problem, even if I have partially solved it, with select, union and nested queries which are not elegant.
For exemple :
1) INPUT : I have a list of strings :
thestrings
varchar(9)
--------------
1000
1000-0001
1000-0002
2000*
2000-0001
2000-0002
3000*
3000-00*
3000-0001
3000-0002
2) OUTPUT : That I would like my "special group by" return :
1000
1000-0001
1000-0002
2000*
3000*
Because 2000-0001 and 2000-0002 are include in 2000*,
and because 3000-00*, 3000-0001 and 3000-0002 are includes in 3000*
3) SQL query I do :
SELECT every strings ending with *
UNION
SELECT every string where the begining NOT IN (SELECT every string ending with *) <-- with multiple inelegant left functions and NOT IN subqueries
4) That what I'm doing return :
1000
1000-0001
1000-0002
2000*
3000*
3000-00* <-- the problem
The problem is : 3000-00* staying in my result.
So my question is :
How can I generalize my problem? to remove all string who have a same begining string in the list (ending with *) ?
I think of regular expressions, but how to pass a list from a select in a regex ?
Thanks for help.
Select only strings for which no master string exists in the table:
select str
from mytable
where not exists
(
select *
from mytable master
where master.str like '%*'
and master.str <> mytable.str
and rtrim(mytable.str, '*') like rtrim(master.str, '*') || '%'
);
Assuming that only one general pattern can match any given string, the following should do what you want:
select coalesce(tpat.thestring, t.thestring) as thestring
from t left join
t tpat
on t.thestring like replace(tpat.thestring, '*', '%') and
t.thestring <> tpat.thestring
group by coalesce(tpat.thestring, t.thestring);
However, that is not your case. However, you can adjust this with distinct on:
select distinct on (t.thestring) coalesce(tpat.thestring, t.thestring)
from t left join
t tpat
on t.thestring like replace(tpat.thestring, '*', '%') and
t.thestring <> tpat.thestring
order by t.thestring, length(tpat.thestring)

Select statement with column contains '%'

I want to select names from a table where the 'name' column contains '%' anywhere in the value. For example, I want to retrieve the name 'Approval for 20 % discount for parts'.
SELECT NAME FROM TABLE WHERE NAME ... ?
You can use like with escape. The default is a backslash in some databases (but not in Oracle), so:
select name
from table
where name like '%\%%' ESCAPE '\'
This is standard, and works in most databases. The Oracle documentation is here.
Of course, you could also use instr():
where instr(name, '%') > 0
One way to do it is using replace with an empty string and checking to see if the difference in length of the original string and modified string is > 0.
select name
from table
where length(name) - length(replace(name,'%','')) > 0
Make life easy on yourselves and just use REGEXP_LIKE( )!
SQL> with tbl(name) as (
select 'ABC' from dual
union
select 'E%FS' from dual
)
select name
from tbl
where regexp_like(name, '%');
NAME
----
E%FS
SQL>
I read the documentation mentioned by Gordon. The relevent sentence is:
An underscore (_) in the pattern matches exactly one character (as opposed to one byte in a multibyte character set) in the value
Here was my test:
select c
from (
select 'a%be' c
from dual) d
where c like '_%'
The value a%be was returned.
While the suggestions of using instr() or length in the other two answers will lead to the correct answer, they will do so slowly. Filtering on function results simply take longer than filtering on fields.

Searching Technique in SQL (Like,Contain)

I want to compare and select a field from DB using Like keyword or any other technique.
My query is the following:
SELECT * FROM Test WHERE name LIKE '%xxxxxx_Ramakrishnan_zzzzz%';
but my fields only contain 'Ramakrishnan'
My Input string contain some extra character xxxxxx_Ramakrishnan_zzzzz
I want the SQL query for this. Can any one please help me?
You mean you want it the other way round? Like this?
Select * from Test where 'xxxxxx_Ramakrishnan_zzzzz' LIKE '%' + name + '%';
You can use the MySQL functions, LOCATE() precisely like,
SELECT * FROM WHERE LOCATE("Ramakrishnan",input) > 0
Are the xxxxxx and zzzzz bits always 6 and 5 characters? If so, then this is doable with a bit of string cutting.
with Test (id,name) as (
select 1, 'Ramakrishnan'
union
select 2, 'Coxy'
union
select 3, 'xxxxxx_Ramakrishnan_zzzzz'
)
Select * from Test where name like '%'+SUBSTRING('xxxxxx_Ramakrishnan_zzzzz', 8, CHARINDEX('_',SUBSTRING('xxxxxx_Ramakrishnan_zzzzz',8,100))-1)+'%'
Results in:
id name
1 Ramakrishnan
3 xxxxxx_Ramakrishnan_zzzzz
If they are variable lengths, then it will be a horrible construction of SUBSTRING,CHARINDEX, REVERSE and LEN functions.