Select Where clause - sql-server

I am doing a Select in SQL Server and say my Select is pulling the data like this,
ID Col1 Col2 Col3 Col4
1 xx xx xx xx
2 null null null null
3 xx xx null null
I only want the records where not all the rows are Null. In above record, I don't want the row where ID= 2.
How can I do this in where clause?
Thanks.

Do they all have the same datatype? If so
WHERE COALESCE(Col1, Col2, Col3, Col4) IS NOT NULL

An alternate to Martin's solution:
Where Col1 Is Not Null
Or Col2 Is Not Null
Or Col3 Is Not Null
Or Col4 Is Not Null
It should be noted that if any of the columns are not implicitly castable to the same datatype (e.g. all varchar or all ints), that COALESCE will throw an error.

Where not ( Col1 Is Null
And Col2 Is Null
And Col3 Is Null
And Col4 Is Null)
This will make sure that all the columns are not null

Select Col1, Col2, Col3, Col4
from table
where Col1>''
and Col2>''
and Col3>''
and Col4>''
What this does is it selects all rows that actually have data in them. However, if you have char fields that are balnk but not null that you need to select, you'll have to change this to >=. This query will also utalize a covering index i believe.

Related

How to derive column value based on occurrence of a phrase in Snowflake

I have input table as below
I want to have a derived column with the logic like
If for single value of COL1, if field COL2 has 'ABC' then DERIVED_COL will be filled with 'ABC_FIXED', if for a single value of COL2, if field COL# does not have 'ABC', then DERIVED_COL will be filled with 'ABC_NONFIXED'.
Is this possible in Snowflake?
Just do a self-join with a subset of same table with col2='ABC'. If join produces result means ABC fixed else ABC not fixed.
select orig.col1,orig.col2,
case when abc.col2 is not null then 'ABC_FIXED' else 'ABC_NOTFIXED' end derived_col
from mytable orig
left join (select distinct col1, col2 from mytable where col2='ABC') abc
on abc.col1=orig.col1
Using windowed function:
SELECT *, CASE WHEN COUNT_IF(COL2 = 'ABC') OVER(PARTITION BY COL1) > 0
THEN 'ABC_FIXED' ELSE 'ABC_NOTFIXED'
END AS DERIVED_COL
FROM tab;

If statements within a Query

I'm using a query & importrange combo like this:
=IFERROR(QUERY(IMPORTRANGE("https://docs.google.com/spreadsheets/d/1EizWsVwZfUy1NDRwmmWEpj2OxTGvBjP9-YBbds9xmr0/edit#gid=0", "'Locations'!A2:C"), "select Col3 where Col1='"&J4&"' and Col1<>''"))
But Instead of just searching column 1 and returning the associated value in column 3, I would like it to return the associated value in:
Col3 if the value is in Col1
Col7 if the value is in Col5
Col11 if the value is in Col9
It can throw an error if the value is in more than one place, or return the result at the first occurrence, either way is fine.
I'm trying to do this using "countif" within the query but am not having a much luck.
try:
=IFERROR(QUERY({
IMPORTRANGE("1EizWsVwZfUy1NDRwmmWEpj2OxTGvBjP9-YBbds9xmr0", "Locations!A2:C");
IMPORTRANGE("1EizWsVwZfUy1NDRwmmWEpj2OxTGvBjP9-YBbds9xmr0", "Locations!E2:G");
IMPORTRANGE("1EizWsVwZfUy1NDRwmmWEpj2OxTGvBjP9-YBbds9xmr0", "Locations!I2:K")},
"select Col3 where Col1='"&J4&"' and Col1 is not null", ))

How to create table from table with "case" in order to copy and modify original data in Oracle?

Since I have a table with milions of records, I've been looking for a solution to update data in one column more efficiently, without using UNDO tablespace and UPDATE statement.
My idea was to create a second table (copy) X from the target table Y, as follows:
create table X as
select col1,col2,col3, (case when col4 is not null and createdate < sysdate - 180 then null else col4) as col4 from Y;
Then drop table Y and rename X to Y. It creates the table but my test query
select count(col4) from Y where col4 is not null and createdate < sysdate - 180
Shows that there are still some records with original value (looks like case clause does not work as suppose to). When I use the same select in subquery and the exact same condition, like
select count(col4) from (select col1,col2,col3, (case when col4 is not null and createdate < sysdate - 180 then null else col4) as col4 from Y) where col4 is not null and createdate < sysdate - 180
The result is 0. Am I doing something incorrectly?
Well I think I have figured that out:
The problem here is sysdate as I tried to at first clone the table (sysdate1) and then validate the data using sysdate in where conditions (sysdate2 different from the first one)
Subquery print 0 as it takes the same sysdate for both conditions.

NOT IN filter out NULL values

I was trying to filter out some predefined values from a table sample which has two column col1 and col2.
My query:
select *
from sample
where (col1 is not null or col2 is not null)
and col1 not in (1,2)
and col2 not in (3,4);
However, the above query filter out all the null values (in col1 or col2 ).
Example: the below row is filtered out,
col1 col2
---------
7 null
null 8
I get the expected result when i modify the query to below.
select *
from sample
where (col1 is not null or col2 is not null)
and (col1 not in (1,2) or col1 is null)
and (col2 not in (3,4) or col2 is null);
Why NOT IN filters out rows with NULL value even though I am not specified NULL in NOT IN ?
Nothing is equal to NULL, and is anything not equal to NULL. For an expression like NULL NOT IN (1,2), this evaluates to unknown which (importantly) is not true; meaning that the WHERE is not met. This is why your second query, where you handle your NULLs works.
Alternatively, you could use an EXISTS. It's perhaps not an intuitive, but handles NULL values:
WITH VTE AS(
SELECT *
FROM (VALUES(1,3),(2,4),(3,5),(7,NULL),(NULL,8))V(col1,col2))
SELECT *
FROM VTE
WHERE NOT EXISTS(SELECT 1
WHERE Col1 IN (1,2)
AND Col2 IN (3,4));
Try this
SET ANSI_NULLS OFF
select *
from sample
where (col1 is not null or col2 is not null)
and col1 not in (1,2)
and col2 not in (3,4);
ANSI NULL ON/OFF:
This option specifies the setting for ANSI NULL comparisons. When this is on, any query that compares a value with a null returns a 0. When off, any query that compares a value with a null returns a null value (https://blog.sqlauthority.com/2007/03/05/sql-server-quoted_identifier-onoff-and-ansi_null-onoff-explanation/#:~:text=ANSI%20NULL%20ON%2FOFF%3A,null%20returns%20a%20null%20value.).
this discussed in https://stackoverflow.com/questions/129077/null-values-inside-not-in-clause#:~:text=NOT%20IN%20returns%200%20records,not%20the%20value%20being%20tested.

Comparing integers in columns with nulls?

I have a table. The table has two integer columns. Nulls are allowed in each column. The following query works
select * from table where col1=1 and col2 = 2
but neither of the following two queries work
select * from table where col1=1 and col2 != 2 or
select * from table where col1=1 and col2 <> = 2
I am aware that the comparison operators are not supposed to work for columns that have null, but '=' is a comparison operator and the first query above works. I do not understand why the first query works and the second query does not? (If you see any typos just ignore them I tested this with real code any mistakes are just when I transcribed it to this question.)
Here are two sql statements that will allow you to create a table and insert data into it for testing the above queries.
CREATE TABLE Test (
ID int,
Col1 int,
Col2 int)
and the insert statements
INSERT INTO test
(id, col1 , col2)
VALUES
(1,1,NULL),
(2,NULL,2),
(3,1,2)
It may help you understand by examining the results of each query predicate individually using the sample data. Note that both conditions must evaluate to TRUE for a row to be returned due to the AND logical operator.
select * from Test where col1=1 and col2 = 2;
VALUES
(1,1,NULL), --col1=1 is TRUE and col2 = 2 is UNKNOWN
(2,NULL,2), --col1=1 is UNKNOWN and col2 = 2 is TRUE
(3,1,2) --col1=1 is TRUE and col2 = 2 is TRUE: row returned because both are TRUE
select * from table where col1=1 and col2 <> 2
VALUES
(1,1,NULL), --col1=1 is TRUE and col2 <> 2 is UNKNOWN
(2,NULL,2), --col1=1 is UNKNOWN and col2 <> 2 is FALSE
(3,1,2) --col1=1 is TRUE and col2 <> 2 is FALSE
If Col 2 is either 2 or null as in your comment then you need to use IS NULL
select * from table where col1=1 and col2 IS NULL
Or convert the null values to some other non-used value
select * from table where col1=1 and ISNULL(col2, 0) != 2
Sounds like those columns should really be bit fields though to me.

Resources