SQL select not viewing correct data - sql

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')

Related

Oracle SQL String starts with ‘987’ or ‘I’

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;

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.

WHERE for filtering out data based on multiple conditions

Suppose I had a large table TBL_LARGE_TABLE with say 100 columns (column1, column2,...column100 all nullable) and my client gave me a query so i could filter out certain rows:
SELECT * FROM TBL_LARGE_TABLE
WHERE
COLUMN2='00123'
AND
(COLUMN3 LIKE '%garbage%' OR COLUMN3 LIKE '%trash%')
AND
COLUMN100='0';
Now, I want to put the data from TBL_LARGE_TABLE into another table TBL_ANOTHER_LARGE_ONE. What would be the best way to insert from TBL_LARGE_TABLE into TBL_ANOTHER_LARGE_ONE excluding all the rows that will pass the above SELECT statement? I dont want to delete any data, I want the original table to stay as it is. I just want to select the exact opposite of the SELECT statement above.
INSERT INTO TBL_ANOTHER_LARGE_ONE
SELECT *
FROM TBL_LARGE_TABLE
WHERE NOT
(
COLUMN2='00123'
AND
(COLUMN3 LIKE '%garbage%' OR COLUMN3 LIKE '%trash%')
AND
COLUMN100='0
)
INSERT INTO TBL_ANOTHER_LARGE_ONE
SELECT *
FROM TBL_LARGE_TABLE
WHERE
COLUMN2 <>'00123'
AND
(COLUMN3 NOT LIKE '%garbage%' OR COLUMN3 NOT LIKE '%trash%')
AND
COLUMN100 <>'0'
)

Is there a single SQL (or its variations) function to check not equals for multiple columns at once?

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.