sql query exact search than others - sql

I have table that has many columns. But we consider here 2 columns.
Name is Column1 and Column2. And table name is WordTable. I just want to search 50 record bases on those 2 column that match like below.
If I enter "auto" then result should be.
"auto"
"autoa"
"autoab"
.
.
.
Etc
If I enter "maver", result should be
"maver"
"mavera"
"maverr"
"maverx"
"maverydsdb"
Means First word should exact match the rest of after ascending order. And match should be done from any of the tow columns.
Below are my query but doesn't work.
searchWord(value) async {
var res = await db.rawQuery("SELECT *
FROM WordTable
WHERE (Column1 LIKE '$value%' OR Column2 LIKE '$value%')
ORDER BY Column1 ASC, Column2 ASC
LIMIT 50");
List<Word> list =
res.isNotEmpty ? res.map((c) => Word.fromJson(c)).toList() : [];
return list;
}
Getting result but not in expect order.
Where I'm going wrong? Pls guide me.
I'm coming from mobile platform and using "SQFLite" data base so for me query is important.

There are two tricks here. The first is to order by something that doesn't actually exist in the table, ie the part of the word after "$value". You can use sqlite substr and sqlite length to find that part, something like substr(column,length($value)). Since the desired result is the "whole" word, it can be put back together with concatenation operator ||, something like $value||substr(column,length($value)).
The second trick is to select column1 OR column2 into the same result field so they can be ordered as one column. One way to accomplish that would be with a UNION query.
With data like this:
column1 column2
---------- ----------
autob autoa
mavery autoc
maverz mavera
autoz maverq
autoa autob
This query:
select 'auto'||substr(column1,length('auto') + 1) word
from wordTable
where column1 like 'auto%'
UNION
select 'auto'||substr(column2,length('auto')+1)
from wordTable
where column2 like 'auto%'
order by 1
Returns this result:
word
----------
autoa
autob
autoc
autoz
ADDENDUM
Upon further reflection, I rather overthunk it. The first "trick" is moot if you use the UNION with the matching "words" in the same result column as with:
SELECT column1,*
from wordTable
where column1 like '$value%'
UNION
SELECT column2,*
from wordTable
where column2 like '$value%'
ORDER BY 1

I think you need to use + connect string to fill your parameter otherwise you will only execute this sql.
SELECT * FROM WordTable WHERE (Column1 LIKE '$value%' OR Column2 LIKE '$value%') ORDER BY Column1 ASC, Column2 ASC LIMIT 50
I am not sure what language you use I would suggest you use parameters to avoid sql-injection.
"SELECT * FROM WordTable WHERE (Column1 LIKE '"+$value+"%' OR Column2 LIKE '"+$value%+"') ORDER BY Column1 ASC, Column2 ASC LIMIT 50"

You can try this code for order:
SELECT *
FROM WordTable
WHERE (Column1 LIKE '$value%' OR Column2 LIKE '$value%')
ORDER BY Column1 = '$value' DESC, Column1 LIKE '$value%' DESC,
Column2 = '$value' DESC, Column2 LIKE '$value%' DESC,
Column1 ASC, Column2 ASC
LIMIT 50

Related

How do I compare multiple fields to multiple substrings?

I'm working on a Presto query that checks multiple fields against multiple substrings to see if at least one field contains any of the given substrings. For example, let's say I want to check if either column1, column2, or column3 contain test, inactive, or deprecated.
I could write multiple LIKE comparisons for each field and substring, but it seems a bit repetitive.
-- Functional, but cumbersome
SELECT *
FROM table
WHERE
column1 LIKE '%test%' OR column1 LIKE '%inactive%' OR column1 LIKE '%deprecated%'
OR column2 LIKE '%test%' OR column2 LIKE '%inactive%' OR column2 LIKE '%deprecated%'
OR column3 LIKE '%test%' OR column3 LIKE '%inactive%' OR column3 LIKE '%deprecated%'
I can simplify it a bit with regexp_like() but it's still a bit repetitive.
-- Functional, less cumbersome
SELECT *
FROM table
WHERE
REGEXP_LIKE(column1, 'test|inactive|deprecated')
OR REGEXP_LIKE(column2, 'test|inactive|deprecated')
OR REGEXP_LIKE(column3, 'test|inactive|deprecated')
Ideally I'd like to have a single comparison that covers each field and substring.
-- Non functional pseudocode
SELECT *
FROM table
WHERE (column1, column2, column3) LIKE ('%test%', '%inactive%', '%deprecated%')
Is there a simple way to compare multiple fields to multiple substrings?
You could search on a concatenation of the three columns.
SELECT *
FROM table
WHERE
REGEXP_LIKE(column1+' ' + column2+' ' +column3, 'test|inactive|deprecated')
Also you could put the words your matching against as rows in a new MatchWord table, then be able to add/remove words without changing your query.
SELECT
*
FROM
Data d
WHERE
EXISTS(
SELECT
*
FROM MatchWord w
WHERE
d.column1+' ' +d.column2+' ' +d.column3 LIKE '%' + w.word + '%'
)

How to search a row to see if any of the columns contain a certain string? In SQL

I have a table with 10 columns that each contain string values. I want to run a query that will return any of the rows which have any column value that matches a given string or set of strings.
Is there any way to do this?
The DBMS is MsSQL
if you want exact match, you can use IN keyword and check in all columns
SELECT *
FROM tablename
WHERE 'your string' IN (column1, column2, )
if you want partial match then you have to use LIKE
SELECT *
FROM tablename
WHERE column1 LIKE '%your string%' or column2 LIKE '%your string%' ...
or you can add all columns and do one LIKE check
SELECT *
FROM tablename
WHERE CONCAT(column1,'#',column2,'#',column3,'#',...) LIKE '%your string%'

Between and Like in same where clause

I'm trying to execute a query using Oracle SQL but I get an error. I wan to return a value based on the range of the parameters entered. See my example query below:
select column1, column2, column3
from table_name
where column1 between like '1234%' and like '1239%
The datatype for column1 is varchar2.
Instead of like use SUBSTR():
select column1, column2, column3
from table_name
where substr(column1,4) between '1234' and '1239'
/
Also, you may wish to cast the strings to numbers, to ensure you get the correct behaviour, although that depends on your data.
where to_number(substr(column1,4)) between 1234 and 1239
I am guessing this does what you want:
where column1 >= '1234' and
column1 < '1240'
This more index-friendly, so it can use an index on column1 -- which is an advantage of regular expressions.

SQL Searching - Two Columns Varying Values

Based on a poor database design beyond my control, I am now having to deal with something new (for me). I am hoping someone can assist me.
We have two columns in the database: "Column1" and "Column2"
Column1 can have a value of Breakfast/Lunch/Dinner. Column2 is free text and can contain many things.
How can I write a query where I can look for more than one specific value in Column1 and Column2 where both conditions must be true?
Example Code:
Select *
from TestDb
where (Column1 = 'Breakfast' and Column2 like '%banana%')
and (Column1 = 'Lunch' and Column2 like '%pizza%')
The expected result is that we find all subjects who had a banana for breakfast and pizza for lunch (which is why both conditions must be true). We don't want to find subject who just had a banana for breakfast or just pizza for lunch.
If you want to find out a single answer based on two different rows, then one approach is to check for one and then see if the other also exists. You haven't given a lot of info on your schema, so a simple example might be:
SELECT 'FOUND'
FROM TestDB a
WHERE a.Column1 = '100' and a.Column2 like '%hello%'
AND EXISTS (SELECT 1
FROM TestDB b
WHERE b.Column1 = '150' and b.Column2 like '%goodbye%')
Obviously you can change 'FOUND' for whatever relevant data you'd like to return. If there's some kind of identifier you need to match on then you'd add that into the sub select, ie.: AND b.Id = a.Id.
If this doesn't give you what you want, I think you really need to give some examples in your question to clarify.
Where column1 in (100,150) and (column2 like ‘%hello%’ or column2 like ‘%goodbye%’)
You would seem to want something like this:
Select master_id
from TestDb
where (Column1 = '100' and Column2 like '%hello%') or
(Column1 = '150' and Column2 like '%goodbye%')
group by master_id
having count(*) = 2;
This assumes that the rows are unique, so two rows do not match the same condition.
may be we can use union ? I ran into similar thing way back, Union helped me. Please have a look, if it helps.
select * from table1 where column1 ='val1' and column2 ='val2'
union
select * from table1 where column1='val3' and column2 ='val4'
Joins are interesting, self joins are interesting too.

SQL select not viewing correct data

I have earlier been using MySQL and there I could get the correct response with this select query.
SELECT *
FROM TABLE
WHERE COLUMN1 NOT IN ('Done', 'Closed')
AND COLUMN2 IN ('Dude1', 'Dude2', 'Dude3')
Now we have changed db to oracle and there it leaves out if COLUMN1 have no value in it. In another words, it's null/empty.
I have tried what I believe would be the correct way to make the query but it behaves not as I was hoping. Maybe someone have a solution that I could retrieve same information as in MySQL.
Last attempt I ended up with this query
SELECT *
FROM TABLE
WHERE COLUMN1 NOT IN ('Done', 'Closed')
OR COLUMN1 IS NULL
AND COLUMN2 IN ('Dude1', 'Dude2', 'Dude3')
When I run this query I get all that have null/empty as value in COLUMN1 but I also get Dude6 in COLUMN2 from the reply... and I can't figure out how I could do it any other way..
If I remove
OR Column1 IS NULL
I won't get the mysterious Dude6 as responses but I also won't get the rows where column1 is empty/null and with Dude1 in it for example..
You just need parentheses around your OR expression:
SELECT *
FROM TABLE
WHERE
(COLUMN1 NOT IN ('Done','Closed') OR COLUMN1 IS NULL)
AND COLUMN2 IN ('Dude1','Dude2','Dude3')