postgresql - check if a row contains a string without considering spaces - sql

Is it possible to check if a row contains a string without conisdering spaces?
Suppose I have a table like the one above. I want to know if the query column contains a string that may have different consecutive number of space than the one stored or vice versa?
For example: the first row's query is select id, username from postgresql, and the one I want to know if stored in the table is:
select id, username
from postgresql
That is to say the one that I want to know if exists in the table is indented differently and hence has different number of space.

You can use REGEXP_REPLACE; this will likely be very slow on large data set.
SELECT * from table
where REGEXP_REPLACE('select id, username from postgresql ', '\s+$', '') = REGEXP_REPLACE(query, '\s+$', '')

I think you would phrase this as:
where $str ~ replace('select id, username from postgresql', ' ', '[\s]+')
Note: This assumes that your string does not have other regular expression special characters.

Related

SQL: Generate a string from table field and store into another field

I didn't see any similar questions asked on this topic.
I have to write a sql query for selecting a field from table and then generating a string replacing space with '-' and putting in another field.
select title field and replace space with '-' and store in slug for all data
You need to use a REPLACE.
Use the following to test it
SELECT
ID
,Title
,REPLACE(title,' ','-') Slug
FROM tableName;
and if it is good, use the following to populate the field
UPDATE tableName
SET slug = REPLACE(title,' ','-');
Description: REPLACE will do exactly as it sounds, replace all instances of a character (or characters) with the replacement string which you provide.
Here's the link to SQL Server documentation (it's the same for MySQL as well - you have multiple RDBMS tags here): https://learn.microsoft.com/en-us/sql/t-sql/functions/replace-transact-sql?view=sql-server-ver15
#Rajat Singh. It seems to be simply:
update table
set slug = replace(title, ' ', '-')

Select if comma separated string contains a value

I have table
raw TABLE
=========
id class_ids
------------------------
1 1234,12334,12341,1228
2 12281,12341,12283
3 1234,34221,31233,43434,1123
How to define regex to select raws if class_ids contains special id.
If we select raws with '1234' in class_ids result list should not contain raws with '12341' in class_ids.
IDs in column class_ids separated with ,
SELECT FROM raw re WHERE re.class_ids LIKE (regex)
You shouldn't be storing comma separated values in a single column.
However, this is better done using string_to_array() in Postgres instead of a regex:
SELECT *
FROM raw
WHERE '1234'= any(string_to_array(class_ids, ','));
If you really want to de-normalize your data, it's better to store those numbers in a proper integer array, instead of comma separated list of strings
A simple way uses like:
where ',' || re.class_ids || ',' like '%,1234,%'
However, this is not the real issue. You should not be storing lists of ids in a string. The SQLish way of storing them would have a table with one row per id and one row per class_id. This is called a junction table.
Even if you don't use a separate table, you should at least use Postgres's built-in mechanisms, such as an array. However, a separate table is much the preferred method, because you can explicitly declare foreign key relationships.
If you really want to do this with regular expressions, you can use the ~ operator:
SELECT FROM raw re WHERE re.class_ids ~ '^(^|,)1234(,|$)$';
But I prefer a_horse_with_no_name's answer that uses arrays.

SQL - just view the description for explanation

I would like to ask if it is possible to do this:
For example the search string is '009' -> (consider the digits as string)
is it possible to have a query that will return any occurrences of this on the database not considering the order.
for this example it will return
'009'
'090'
'900'
given these exists on the database. thanks!!!!
Use the Like operator.
For Example :-
SELECT Marks FROM Report WHERE Marks LIKE '%009%' OR '%090%' OR '%900%'
Split the string into individual characters, select all rows containing the first character and put them in a temporary table, then select all rows from the temporary table that contain the second character and put these in a temporary table, then select all rows from that temporary table that contain the third character.
Of course, there are probably many ways to optimize this, but I see no reason why it would not be possible to make a query like that work.
It can not be achieved in a straight forward way as there is no sort() function for a particular value like there is lower(), upper() functions.
But there is some workarounds like -
Suppose you are running query for COL A, maintain another column SORTED_A where from application level you keep the sorted value of COL A
Then when you execute query - sort the searchToken and run select query with matching sorted searchToken with the SORTED_A column

How to concatenate row values for use in WHERE clause of T-SQL query

I want to write a query in T-SQL to perform a search on two concatenated columns. The two columns are fname and lname. Here is what I have so far:
SELECT
fname,
lname,
...
FROM
users
JOIN
othertable ON foo=bar
WHERE
fname+' '+lname LIKE '%query%'
SQL server doesn't like that syntax, though. How do I structure the query so that I can perform a WHERE LIKE operation that searches through two concatenated columns, allowing me to search the user's full name, rather than just first name and last name individually?
I can only suggest that one of fname or lname is NULL so the LIKE fails., (NULL concat anything is null)
Try
...
ISNULL(fname, '') + ' ' + ISNULL(lname, '') LIKE '%query%'
However, I would use a computed column and consider indexing it because this will run awfully.
My suggestion is to add a calculated column to your table for full_name
calculated column examples:
--drop table #test
create table #test (test varchar (10) , test2 varchar (5),[Calc] AS right(test, 3))
Insert #test
values('hello', 'Bye')
Insert #test
values('hello-bye', null)
Alter table #test
add [MyComputedColumn] AS substring(test,charindex('-',test), len(test)),
Concatenatedcolum as test+ ' ' +test2
select * from #test
As you can see you may have to play around a bit until you get the results you want. Do that in a temp table first to avoid having to restructure the database table multiple times. For names, especially if you are using middle name which is often blank, you may need to add some code to handle nulls. You may also need to have code sometimes to cast to the same datatype if one filed you are concatenating is an int for instance and the other a varchar.
I think one of the join conditions might be causing a problem. Try rewriting it, you may find the error goes away ;)

How can I run a query on IDs in a string?

I have a table A with this column:
IDS(VARCHAR)
1|56|23
I need to run this query:
select TEST from TEXTS where ID in ( select IDS from A where A.ID = xxx )
TEXTS.ID is an INTEGER. How can I split the string A.IDS into several ints for the join?
Must work on MySQL and Oracle. SQL99 preferred.
First of all, you should not store data like this in a column. You should split that out into a separate table, then you would have a normal join, and not this problem.
Having said that, what you have to do is the following:
Convert the number to a string
Pad it with the | (your separator) character, before it, and after it (I'll tell you why below)
Pad the text you're looking in with the same separator, before and after
Do a LIKE on it
This will run slow!
Here's the SQL that does what you want (assuming all the operators and functions work in your SQL dialect, you don't say what kind of database engine this is):
SELECT
TEXT -- assuming this was misspelt?
FROM
TEXTS -- and this as well?
JOIN A ON
'|' + A.IDS + '|' LIKE '%|' + CONVERT(TEXTS.ID) + '|%'
The reason why you need to pad the two with the separator before and after is this: what if you're looking for the number 5? You need to ensure it wouldn't accidentally fit the 56 number, just because it contained the digit.
Basically, we will do this:
... '|1|56|23|' LIKE '%|56|%'
If there is ever only going to be 1 row in A, it might run faster if you do this (but I am not sure, you would need to measure it):
SELECT
TEXT -- assuming this was misspelt?
FROM
TEXTS -- and this as well?
WHERE
(SELECT '|' + IDS + '|' FROM A) LIKE '%|' + CONVERT(TEXTS.ID) + '|%'
If there are many rows in your TEXTS table, it will be worth the effort to add code to generate the appropriate SQL by first retrieving the values from the A table, construct an appropriate SQL with IN and use that instead:
SELECT
TEXT -- assuming this was misspelt?
FROM
TEXTS -- and this as well?
WHERE
ID IN (1, 56, 23)
This will run much faster since now it can use an index on this query.
If you had A.ID as a column, and the values as separate rows, here's how you would do the query:
SELECT
TEXT -- assuming this was misspelt?
FROM
TEXTS -- and this as well?
INNER JOIN A ON TEXTS.ID = A.ID
This will run slightly slower than the previous one, but in the previous one you have overhead in having to first retrieve A.IDS, build the query, and risk producing a new execution plan that has to be compiled.