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.
Related
I am using Oracle SQL Developer. I need to find the rows where column1 starts with ‘987’ or ‘I’. Column1 is a String(18). Some sample patterns in this column include: 9(9), 9(12), and others. I am not familiar with the code to see how a column starts with certain values in Oracle SQL. Sample Code is below. Attempt below.
Code
select * from table1
where column1
Attempt Code
SELECT
REGEXP_SUBSTR(column1,
'987') "REGEXP_SUBSTR"
FROM table1;
You can use a regular expression for this:
where regexp_like(column1, '^(987|I)')
You just need to use LIKE.
select *
from table1
where column1 like '987%' or column1 like 'I%';
CREATE TABLE hs(WH VARCHAR2(100));
SELECT
*
FROM
hs
WHERE
REGEXP_LIKE(WH,'^987|^I', 'i')
ORDER BY WH;
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
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')
I want to compare multiple column's NULL values. eg. Assume I have 3 columns in my table from which I have to find out NOT NULL values. I am using following code :
select * from table1 where
column1 is not null
and column2 is not null
and column3 is not null
I don't want to use this code as it uses "and" multiple times if columns goes on increasing.
Anybody have option to this in Oracle 11g ?
I agree with the comment that your query is fine as is. If the columns that you are checking are all of a numeric variety then you can use Oracle's behavior with null values to your advantage to shorten the query like this:
select * from table 1
where
(
column1
+ column2
+ column3
) is not null;
If any of the listed columns are null then the sum will be null also. Unfortunately, if you have strings instead--null strings concatenate just fine, so the same approach doesn't work with them.
You can use
COALESCE (expr1, expr2)
which is equivalent to
CASE WHEN expr1 IS NOT NULL THEN expr1 ELSE expr2 END
Your syntax would be
coalesce(column1,....,columnn) is not null
You can use this instead of the COALESCE:
SELECT *
FROM table1
WHERE column1 || column2 || column3 || column4 IS NOT NULL;
Tim Rhyne answers well. If you had all string columns, your where clause could be:
WHERE LENGTH(COLUMN1)+LENGTH(COLUMN2)+LENGTH(COLUMN3) IS NOT NULL
If you had a mix of string and numeric:
WHERE COLUMN_INTEGER1+COLUMN_INTEGER2+LENGTH(COLUMN_STRING3) IS NOT NULL
Just as I can check if a column does not equal one of the strings given in a set.
SELECT * FROM table1 WHERE column1 NOT IN ('string1','string2','string3');
Is there a single function that I can make sure that multiple columns does not equal a single string? Maybe like this.
SELECT * FROM table1 WHERE EACH(column1,column2,column3) <> 'string1';
Such that it gives the same effect as:
SELECT * FROM table1 WHERE column1 <> 'string1'
AND column2 <> 'string1'
AND column3 <> 'string1';
If not, what's the most concise way to do so?
I believe you can just reverse the columns and constants in your first example:
SELECT * FROM table1 WHERE 'string1' NOT IN (column1, column2, column3);
This assumes you are using SQL Server.
UPDATE:
A few people have pointed out potential null comparison problems (even though your desired query would have the same potential problem). This could be worked around by using COALESCE in the following way:
SELECT * FROM table1 WHERE 'string1' NOT IN (
COALESCE(column1,'NA'),
COALESCE(column2,'NA'),
COALESCE(column3,'NA')
);
You should replace 'NA' with a value that will not match whatever 'string1' is. If you do not allow nulls for columns 1,2 and 3 this is not even an issue.
No, there is no standard SQL way to do this. Barring any special constraints on what the string fields contain there's no more concise way to do it than you've already hit upon (col1 <> 'String1' AND col2 <> 'String2').
Additionally, this kind of requirement is often an indication that you have a flaw in your database design and that you're storing the same information in several different columns. If that is true in your case then consider refactoring if possible into a separate table where each column becomes its own row.
The most concise way to do this is
SELECT * FROM table1 WHERE column1 <> 'string1'
AND column2 <> 'string1'
AND column3 <> 'string1';
Yes, I cut & pasted that from your original question. :-)
I'm more concerned why you're wanting to compare against all three columns. It sounds like you might have a table that needs normalization. What are the actual columns of column1, column2 and column3. Are they something like phone1, phone2, and phone3? Perhaps those three columns should actually be in a subtable.