Using IS NOT NULL for multiple columns - sql-server

I want to check for the is not null constraint for multiple columns in a single SQL statement in the WHERE clause, is there a way to do so?
Also I don't want want to enforce the NOT NULL type constraint on the column definition.
SELECT * FROM AB_DS_TRANSACTIONS
WHERE FK_VIOLATION IS NULL
AND TRANSACTION_ID NOT IN(
SELECT distinct TRANSACTION_ID FROM AB_TRANSACTIONS)
AND COUNTRY_ID IS NOT NULL
AND GEO_CUST_COUNTRY_ID IS NOT NULL
AND INVOICE_DATE IS NOT NULL
AND ABB_GLOBALID IS NOT NULL
AND SALES_ORG_ID IS NOT NULL
AND DIST_ID IS NOT NULL
AND CUSTOMER_ID IS NOT NULL
AND REPORT_UNIT_ID IS NOT NULL
AND CURR_INVOICE IS NOT NULL
AND DIVISION_CODE IS NOT NULL
So instead of using IS NOT NULL again and again I want to simplify things

You can use
SELECT * FROM table1
WHERE NOT (Column1 IS NULL OR
Column2 IS NULL OR
Column3 IS NULL OR
Column4 IS NULL
IS NOT NULL)
As per OP comment, Updating answer
Inserting Rows by Using INSERT and SELECT Subqueries
INSERT INTO Table_A
SELECT column1, column2, column3,column4
FROM Table_B
WHERE NOT (Column1 IS NULL OR
Column2 IS NULL OR
Column3 IS NULL OR
Column4 IS NULL
IS NOT NULL);
Your query
I am able to reduce 50 chars approx
SELECT * FROM AB_DS_TRANSACTIONS
WHERE
FK_VIOLATION IS NULL
AND TRANSACTION_ID NOT
IN(SELECT distinct TRANSACTION_ID FROM AB_TRANSACTIONS)
AND
NOT (
COUNTRY_ID IS NULL
OR GEO_CUST_COUNTRY_ID IS NULL
OR INVOICE_DATE IS NULL
OR ABB_GLOBALID IS NULL
OR SALES_ORG_ID IS NULL
OR DIST_ID IS NULL
OR CUSTOMER_ID IS NULL
OR REPORT_UNIT_ID IS NULL
OR CURR_INVOICE IS NULL
OR DIVISION_CODE IS NULL
)

SELECT * FROM AB_DS_TRANSACTIONS
WHERE COALESCE(COUNTRY_ID,GEO_CUST_COUNTRY_ID,INVOICE_DATE,ABB_GLOBALID,SALES_ORG_ID,DIST_ID,CUSTOMER_ID,REPORT_UNIT_ID,CURR_INVOICE,DIVISION_CODE) IS NOT NULL

I think the syntax that you are looking for to show only those rows where all are not null is this
SELECT * from table_B
where COLUMN1 is not null and COLUMN2 is not null and COLUMN3 is not null

In BigQuery (might work in other db)- I would use the concat-function. Make sure to have strings or cast fields to strings where needed. Concat returns null if one of the fields is null.
SELECT * FROM AB_DS_TRANSACTIONS
WHERE FK_VIOLATION IS NULL
AND TRANSACTION_ID NOT IN(
SELECT distinct TRANSACTION_ID FROM AB_TRANSACTIONS)
AND concat(COUNTRY_ID,GEO_CUST_COUNTRY_ID,INVOICE_DATE,ABB_GLOBALID,SALES_ORG_ID,DIST_ID,CUSTOMER_ID,REPORT_UNIT_ID,CURR_INVOICE,DIVISION_CODE) IS NOT NULL

I think one strategy can be using least function?
The limitation here would be that all the arguments must be of the same type, so looks like OP's columns may need to be converted to a str or something.
If we can get past that limitation, I think the below should work to check if any of the columns are null:
SELECT *
FROM AB_DS_TRANSACTIONS
WHERE FK_VIOLATION IS NULL
AND TRANSACTION_ID NOT IN( SELECT distinct TRANSACTION_ID FROM AB_TRANSACTIONS)
AND least(COUNTRY_ID
,GEO_CUST_COUNTRY_ID
,INVOICE_DATE
,ABB_GLOBALID
,SALES_ORG_ID
,DIST_ID
,CUSTOMER_ID
,REPORT_UNIT_ID
,CURR_INVOICE
,DIVISION_CODE
) IS NOT NULL
;
ps - using snowflake.

It seems like this should be the elegant one:
(at least for newer versions of MSSQL)
SELECT * FROM tbl WHERE NOT COL1+COL2+COL3+COL4 IS NULL

Related

Referenced CTE in CASE expression is returning null values. My CTE works correctly as standalone query

I have a query that works as intended, and I need to build upon it to include a new column that has conditional values. The new column will result with either a date or a string 'na'. To accomplish this, I wrote a CASE statement, and then referenced the CTE within the statement to provide the conditional logic.
The main query (without the CASE statement addition) works as a standalone query, and the CTE works correctly and provides the correct date when it is ran as an independent query.
This is my first time including an INSERT statement. Please let me know if I messed this up.
Main query table:
CREATE TABLE mainquery(
Region_ID INTEGER NOT NULL PRIMARY KEY
,messageid INTEGER NOT NULL
,name VARCHAR(50) NOT NULL
,DateReceived DATETIME NOT NULL
,Datemodified DATETIME NOT NULL
,Messagestatus INTEGER NOT NULL
,clientid VARCHAR(255)
,ClientFirstName VARCHAR(255) NOT NULL
,ClientLastName VARCHAR(255) NOT NULL
,clientdob DATETIME NOT NULL
,Supervisorid INTEGER NOT NULL
,visitid VARCHAR(255) NOT NULL
,SuperName VARCHAR(255) NOT NULL
,SuperID VARCHAR(255) NOT NULL
,colldate VARCHAR(255) NOT NULL
,colltime VARCHAR(255) NOT NULL
,Ordername VARCHAR(255) NOT NULL
,errorlogs VARCHAR(8000) NOT NULL
,comments VARCHAR(255)
,last_visit_date DATETIME
);
INSERT INTO mainquery(Region_ID,messageid,name,DateReceived,Datemodified,Messagestatus,clientid,ClientFirstName,ClientLastName,clientdob,Supervisorid,visitid,SuperName,SuperID,colldate,colltime,Ordername,errorlogs,comments,last_visit_date) VALUES (1,116113842,'R1_OG','2022-06-09 13:07:52.000','2022-06-09 13:07:52.000',4,'123456789','Fake','Name','1980-01-01 00:00:00.000',123,'741852963','Joe','J1234','2022-05-06','16:27:00','fake_order','Supervisor Match not found',NULL,NULL);
INSERT INTO mainquery(Region_ID,messageid,name,DateReceived,Datemodified,Messagestatus,clientid,ClientFirstName,ClientLastName,clientdob,Supervisorid,visitid,SuperName,SuperID,colldate,colltime,Ordername,errorlogs,comments,last_visit_date) VALUES (2,159753205,'SEL North','2022-03-12 04:07:85.000','2018-06-25 12:07:00.000',2,'963741258','Funny','Namely','1999-02-03 00:00:00.000',98524,'159654','David','DL652','2018-01-24','09:03:00','real_fake','Supervisor Match not found',NULL,NULL);
INSERT INTO mainquery(Region_ID,messageid,name,DateReceived,Datemodified,Messagestatus,clientid,ClientFirstName,ClientLastName,clientdob,Supervisorid,visitid,SuperName,SuperID,colldate,colltime,Ordername,errorlogs,comments,last_visit_date) VALUES (3,951789369,'Blue_South','2022-03-11 12:08:33.000','2022-03-11 12:08:33.001',2,NULL,'Who','Ami','2000-08-11 00:00:00.000',789456,'963123','Shirley','S852','2017-05-14','09:30:00','example_order','Client Match not found','here is a comment','na');
INSERT INTO mainquery(Region_ID,messageid,name,DateReceived,Datemodified,Messagestatus,clientid,ClientFirstName,ClientLastName,clientdob,Supervisorid,visitid,SuperName,SuperID,colldate,colltime,Ordername,errorlogs,comments,last_visit_date) VALUES (4,294615883,'Mtn-Dew','2017-09-06 16:20:00.000','2017-09-06 16:20:00.001',2,NULL,'Why','Tho','1970-11-20 00:00:00.000',9631475,'159654852','Bob','B420','2022-09-22','10:25:31','example_example','Client Match not found',NULL,'na');
INSERT INTO mainquery(Region_ID,messageid,name,DateReceived,Datemodified,Messagestatus,clientid,ClientFirstName,ClientLastName,clientdob,Supervisorid,visitid,SuperName,SuperID,colldate,colltime,Ordername,errorlogs,comments,last_visit_date) VALUES (5,789963258,'Home-Base','2022-07-11 15:22:40.000','2022-07-11 15:22:40.001',2,NULL,'Where','Aru','1987-01-06 00:00:00.000',805690123,'805460378','Carlos','C999','2022-07-11','07:30:45','order_order','Client Match not found',NULL,'na');
CTE temporary table:
CREATE TABLE CTE(
uid INTEGER NOT NULL PRIMARY KEY
,clientdob DATETIME NOT NULL
,clienttype INTEGER NOT NULL
,date DATETIME NOT NULL
,visitid VARCHAR(255) NOT NULL
,Region_ID INTEGER NOT NULL
,facilityid INTEGER NOT NULL
,locationid INTEGER NOT NULL
);
INSERT INTO CTE(uid,clientdob,clienttype,date,visitid,Region_ID,facilityid,locationid) VALUES (123456789,'1980-01-01 00:00:00.000',3,'2022-09-18 00:00:00.000','741852963',1,240,32);
INSERT INTO CTE(uid,clientdob,clienttype,date,visitid,Region_ID,facilityid,locationid) VALUES (963741258,'1999-02-03 00:00:00.000',3,'2022-05-11 00:00:00.000','159654',2,606,123);
INSERT INTO CTE(uid,clientdob,clienttype,date,visitid,Region_ID,facilityid,locationid) VALUES (852654320,'1994-05-11 00:00:00.000',3,'2019-03-18 00:00:00.000','123456',3,632,12);
INSERT INTO CTE(uid,clientdob,clienttype,date,visitid,Region_ID,facilityid,locationid) VALUES (85360123,'1997-08-16 00:00:00.000',3,'2021-02-19 00:00:00.000','7896451',4,856,147);
INSERT INTO CTE(uid,clientdob,clienttype,date,visitid,Region_ID,facilityid,locationid) VALUES (85311456,'1964-10-31 00:00:00.000',3,'2016-02-14 00:00:00.000','85263',5,852,15);
Expected view:
screenshot of wide table
Edited to add: I goofed with the 'expected view' screenshot. The screenshot shows an example of what the table looks like right now. The desired view is for there to be dates in last_visit_date (in the appropriate rows), instead of Null.
My issue is the following: the query still works with the new CASE statement and the CTE, except that instead of providing the proper date in the new column, it returns a Null value.
Am I approaching this query with the wrong idea? I thought I was on the right path but now I am doubting myself. I tried utilizing a subquery instead of a CTE, but I received an error message stating that the query could not be completed due to there being more than one result per row.
Here is my main query and associated CTE:
WITH last_visit (uid, clientdob, clienttype, date, visitid, Region_ID, facilityid, locationid) AS
(
SELECT DISTINCT
u.uid, u.clientdob, u.clienttype,
CONVERT(varchar, v.date) AS last_visit,
v.visitid, u.Region_ID, v.facilityid, v.locationid
FROM
users u
LEFT JOIN
visit v ON u.uid = v.clientid
AND u.Region_ID = v.Region_ID
WHERE
v.date = (SELECT MAX(v.date) FROM visit v WHERE v.clientid = u.uid)
AND u.clienttype = 3
AND u.uid <> 8663
AND u.ulname NOT LIKE '%test%'
AND u.ulname NOT LIKE '%unidentified%'
AND u.delflvg = 0
AND v.visittype = 1
AND v.facilityid <> 0
AND v.deleteflag = 0
)
SELECT
r.Region_ID, r.messageid, l.name, r.DateReceived, r.DateModified,
r.MessageStatus, r.clientid, r.ClientFirstName, r.ClientLastName, r.clientdob,
r.Supervisorid, r.visitid, r.SuperName, r.SuperID, r.colldate, r.colltime,
r.OrderName, r.errorlogs, a.comments,
CASE
WHEN r.errorlogs LIKE 'Supervisor Match not found'
THEN lv.date
ELSE 'na'
END AS last_visit_date
FROM
electronicresults r
JOIN
recelectronicresults a ON r.messageid = a.messageid
AND r.Region_ID = a.Region_ID
LEFT OUTER JOIN
users u ON r.clientid = u.uid
LEFT OUTER JOIN
visit v ON r.clientid = v.clientid AND r.visitid = v.visitid
LEFT OUTER JOIN
last_visit lv ON r.visitid = lv.visitid
AND r.clientid = lv.uid
JOIN
lblist l ON r.lbid = l.id
AND r.Region_ID = l.Region_ID
WHERE
r.MessageStatus IN (0, 2, 4)
AND a.actiontaken = 0
AND l.deleteflag = 0
GROUP BY
r.Region_ID, r.messageid, l.name, r.DateReceived, r.DateModified,
r.MessageStatus, r.clientid, r.ClientFirstName, r.ClientLastName,
r.clientdob, r.Supervisorid, r.visitid, r.SuperName, r.SuperID,
r.colldate, r.colltime, r.OrderName, r.errorlogs, a.comments, lv.date
I thank you for taking the time to read this, and any support, hints, tips are greatly appreciated
I was hopeful when you provided a script to create tables and sample data, but unfortunately the script you provided does not work - you cannot INSERT the value 'na' in a DATETIME column as was pointed out. Also, one of the sample DATETIME values is not valid: '2022-03-12 04:07:85.000' (there is no time with 85 seconds). Anyway, I corrected the issues and pressed forward.
There is one issue in your sample query - the CASE statement returns a DATETIME in one case and a VARCHAR in the other case. This is not legal - all cases must return the same data type. Instead of returning 'na' I opted for NULL.
Once I commented out all the tables you did not include, I was able to get a running query:
CREATE TABLE mainquery(
Region_ID INTEGER NOT NULL PRIMARY KEY
,messageid INTEGER NOT NULL
,name VARCHAR(50) NOT NULL
,DateReceived DATETIME NOT NULL
,Datemodified DATETIME NOT NULL
,Messagestatus INTEGER NOT NULL
,clientid VARCHAR(255)
,ClientFirstName VARCHAR(255) NOT NULL
,ClientLastName VARCHAR(255) NOT NULL
,clientdob DATETIME NOT NULL
,Supervisorid INTEGER NOT NULL
,visitid VARCHAR(255) NOT NULL
,SuperName VARCHAR(255) NOT NULL
,SuperID VARCHAR(255) NOT NULL
,colldate VARCHAR(255) NOT NULL
,colltime VARCHAR(255) NOT NULL
,Ordername VARCHAR(255) NOT NULL
,errorlogs VARCHAR(8000) NOT NULL
,comments VARCHAR(255)
,last_visit_date DATETIME
);
INSERT INTO mainquery(Region_ID,messageid,name,DateReceived,Datemodified,Messagestatus,clientid,ClientFirstName,ClientLastName,clientdob,Supervisorid,visitid,SuperName,SuperID,colldate,colltime,Ordername,errorlogs,comments,last_visit_date) VALUES (1,116113842,'R1_OG','2022-06-09 13:07:52.000','2022-06-09 13:07:52.000',4,'123456789','Fake','Name','1980-01-01 00:00:00.000',123,'741852963','Joe','J1234','2022-05-06','16:27:00','fake_order','Supervisor Match not found',NULL,NULL);
INSERT INTO mainquery(Region_ID,messageid,name,DateReceived,Datemodified,Messagestatus,clientid,ClientFirstName,ClientLastName,clientdob,Supervisorid,visitid,SuperName,SuperID,colldate,colltime,Ordername,errorlogs,comments,last_visit_date) VALUES (2,159753205,'SEL North','2022-03-12 04:07:55.000','2018-06-25 12:07:00.000',2,'963741258','Funny','Namely','1999-02-03 00:00:00.000',98524,'159654','David','DL652','2018-01-24','09:03:00','real_fake','Supervisor Match not found',NULL,NULL);
INSERT INTO mainquery(Region_ID,messageid,name,DateReceived,Datemodified,Messagestatus,clientid,ClientFirstName,ClientLastName,clientdob,Supervisorid,visitid,SuperName,SuperID,colldate,colltime,Ordername,errorlogs,comments,last_visit_date) VALUES (3,951789369,'Blue_South','2022-03-11 12:08:33.000','2022-03-11 12:08:33.001',2,NULL,'Who','Ami','2000-08-11 00:00:00.000',789456,'963123','Shirley','S852','2017-05-14','09:30:00','example_order','Client Match not found','here is a comment',NULL);
INSERT INTO mainquery(Region_ID,messageid,name,DateReceived,Datemodified,Messagestatus,clientid,ClientFirstName,ClientLastName,clientdob,Supervisorid,visitid,SuperName,SuperID,colldate,colltime,Ordername,errorlogs,comments,last_visit_date) VALUES (4,294615883,'Mtn-Dew','2017-09-06 16:20:00.000','2017-09-06 16:20:00.001',2,NULL,'Why','Tho','1970-11-20 00:00:00.000',9631475,'159654852','Bob','B420','2022-09-22','10:25:31','example_example','Client Match not found',NULL,NULL);
INSERT INTO mainquery(Region_ID,messageid,name,DateReceived,Datemodified,Messagestatus,clientid,ClientFirstName,ClientLastName,clientdob,Supervisorid,visitid,SuperName,SuperID,colldate,colltime,Ordername,errorlogs,comments,last_visit_date) VALUES (5,789963258,'Home-Base','2022-07-11 15:22:40.000','2022-07-11 15:22:40.001',2,NULL,'Where','Aru','1987-01-06 00:00:00.000',805690123,'805460378','Carlos','C999','2022-07-11','07:30:45','order_order','Client Match not found',NULL,NULL);
CREATE TABLE CTE(
uid INTEGER NOT NULL PRIMARY KEY
,clientdob DATETIME NOT NULL
,clienttype INTEGER NOT NULL
,date DATETIME NOT NULL
,visitid VARCHAR(255) NOT NULL
,Region_ID INTEGER NOT NULL
,facilityid INTEGER NOT NULL
,locationid INTEGER NOT NULL
);
INSERT INTO CTE(uid,clientdob,clienttype,date,visitid,Region_ID,facilityid,locationid) VALUES (123456789,'1980-01-01 00:00:00.000',3,'2022-09-18 00:00:00.000','741852963',1,240,32);
INSERT INTO CTE(uid,clientdob,clienttype,date,visitid,Region_ID,facilityid,locationid) VALUES (963741258,'1999-02-03 00:00:00.000',3,'2022-05-11 00:00:00.000','159654',2,606,123);
INSERT INTO CTE(uid,clientdob,clienttype,date,visitid,Region_ID,facilityid,locationid) VALUES (852654320,'1994-05-11 00:00:00.000',3,'2019-03-18 00:00:00.000','123456',3,632,12);
INSERT INTO CTE(uid,clientdob,clienttype,date,visitid,Region_ID,facilityid,locationid) VALUES (85360123,'1997-08-16 00:00:00.000',3,'2021-02-19 00:00:00.000','7896451',4,856,147);
INSERT INTO CTE(uid,clientdob,clienttype,date,visitid,Region_ID,facilityid,locationid) VALUES (85311456,'1964-10-31 00:00:00.000',3,'2016-02-14 00:00:00.000','85263',5,852,15);
SELECT
r.Region_ID, r.messageid, r.DateReceived, r.DateModified,
r.MessageStatus, r.clientid, r.ClientFirstName, r.ClientLastName, r.clientdob,
r.Supervisorid, r.visitid, r.SuperName, r.SuperID, r.colldate, r.colltime,
r.OrderName, r.errorlogs,
CASE
WHEN r.errorlogs LIKE 'Supervisor Match not found'
THEN lv.date
ELSE NULL
END AS last_visit_date
FROM
mainquery r
LEFT OUTER JOIN
CTE lv ON r.visitid = lv.visitid
AND r.clientid = lv.uid
WHERE
r.MessageStatus IN (0, 2, 4)
GROUP BY
r.Region_ID, r.messageid, r.DateReceived, r.DateModified,
r.MessageStatus, r.clientid, r.ClientFirstName, r.ClientLastName,
r.clientdob, r.Supervisorid, r.visitid, r.SuperName, r.SuperID,
r.colldate, r.colltime, r.OrderName, r.errorlogs, lv.date
Here is the output:
Region_ID
messageid
DateReceived
DateModified
MessageStatus
clientid
ClientFirstName
ClientLastName
clientdob
Supervisorid
visitid
SuperName
SuperID
colldate
colltime
OrderName
errorlogs
last_visit_date
1
116113842
2022-06-09 13:07:52.000
2022-06-09 13:07:52.000
4
123456789
Fake
Name
1980-01-01 00:00:00.000
123
741852963
Joe
J1234
2022-05-06
16:27:00
fake_order
Supervisor Match not found
2022-09-18 00:00:00.000
2
159753205
2022-03-12 04:07:55.000
2018-06-25 12:07:00.000
2
963741258
Funny
Namely
1999-02-03 00:00:00.000
98524
159654
David
DL652
2018-01-24
09:03:00
real_fake
Supervisor Match not found
2022-05-11 00:00:00.000
3
951789369
2022-03-11 12:08:33.000
2022-03-11 12:08:33.000
2
NULL
Who
Ami
2000-08-11 00:00:00.000
789456
963123
Shirley
S852
2017-05-14
09:30:00
example_order
Client Match not found
NULL
4
294615883
2017-09-06 16:20:00.000
2017-09-06 16:20:00.000
2
NULL
Why
Tho
1970-11-20 00:00:00.000
9631475
159654852
Bob
B420
2022-09-22
10:25:31
example_example
Client Match not found
NULL
5
789963258
2022-07-11 15:22:40.000
2022-07-11 15:22:40.000
2
NULL
Where
Aru
1987-01-06 00:00:00.000
805690123
805460378
Carlos
C999
2022-07-11
07:30:45
order_order
Client Match not found
NULL
Again, you will have to add back the JOINs that I had to remove since the tables weren't included as well as some items in the SELECT list, the WHERE clause, and the 'GROUP BY` clause.

Check if a column value is updated to NULL

I have to determine if a column has been updated from a NOT NULL value to NULL in sql server.
Example -
UpdateDate Value Individual
2020-09-02 10:39:03.530 NULL 105292933
2020-08-31 11:05:06.053 Y 105292933
2020-08-31 11:04:32.720 N 105292931
In above example, for Individual 105292933, Value has been updated to NULL from Y. So the result should be the first row. I am new to sql server. Here is what I tried to get the result -
SELECT a.*
FROM tableX AS a
WHERE a.Value <>
( SELECT TOP 1 b.Value
FROM tableX AS b
WHERE a.Individual = b.Individual
AND a.UpdateDate > b.UpdateDate
ORDER BY b.UpdateDate DESC
)
But it is not picking the changes from Y to NULL or N to NULL. Any help will be appreciated.
You can't compare a value with NULL, You can only compare something that is (strings, numbers etc).
In SQL Server NULL != NULL. To check if value is null use WHERE a.value IS NULL
You can change Your code to compare column with some special string (or empty string if You like) if its value is NULL using ISNULL() function.
SELECT a.*
FROM tableX AS a
WHERE ISNULL(a.Value, '*NULL*') <>
( SELECT TOP 1 ISNULL(b.Value, '*NULL*')
FROM tableX AS b
WHERE a.Individual = b.Individual
AND a.UpdateDate > b.UpdateDate
ORDER BY b.UpdateDate DESC
)
A litter more about NULL values here https://www.w3schools.com/sql/sql_null_values.asp
Window functions are usually more efficient than subqueries, when applicable. I would recommend lag():
select *
from (
select t.*, lag(value) over(partition by individual order by updatedate) lag_value
from mytable t
) t
where value is null and lag_value is not null
This query identifies rows were the prior value (based on UpdateDate) was 'Y' or 'N'. Something like this
with lag_cte as (
select *, lag([value]) over(partition by individual order by updatedate) lag_value
from tableX)
select *
from lag_cte
where value is null
and lag_value in('N', 'Y');

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.

How to arrange data in sql server table

I tried many query to achieve the expected result , I couldn't find any solution.
Actual:-
ID | EmpDailyFee | EmpMonthlyFee | CompDailyFee | CompMnthlyFee
1 NULL 12 NULL NULL
1 50 NULL NULL NULL
1 60 NULL NULL NULL
2 50 NULL NULL NULL
3 NULL 30 NULL NULL
Expected :-
ID | EmpDailyFee | EmpMonthlyFee | CompDailyFee | CompMnthlyFee
1 50 12 NULL NULL
1 60 12 NULL NULL
2 50 NULL NULL NULL
3 NULL 30 NULL NULL
This looks like a table smell to me since the rows are sharing the same ID value but with different EmpDailyFee/EmpMonthlyFee values. But in this particular case you can get your expected output like this:
SELECT t1.ID, t1.EmpDailyFee, t2.EmpMonthlyFee
FROM #Test t1
INNER JOIN #Test t2 ON t1.ID = t2.ID
WHERE t1.EmpDailyFee IS NOT NULL AND t2.EmpMonthlyFee IS NOT NULL
UNION ALL
SELECT t1.ID, t1.EmpDailyFee, t1.EmpMonthlyFee
FROM #Test t1
WHERE (t1.EmpDailyFee IS NOT NULL OR t1.EmpMonthlyFee IS NOT NULL) AND t1.ID NOT IN
(
SELECT t3.ID
FROM #Test t3
INNER JOIN #Test t2 ON t3.ID = t2.ID
WHERE t3.EmpDailyFee IS NOT NULL AND t2.EmpMonthlyFee IS NOT NULL
)
This has been tested on SQL Fiddle
Note: The reason why I did not include CompDailyFee and CompMnthlyFee is because the values of both the actual and expected results were NULL. I am trying to write a "simple-as-possible" query based on what OP has provided.
If you're trying to insert or update data this could be the solution, customizing it on your needings
IF EXISTS (SELECT 1 FROM Employee WHERE ID = 1)
UPDATE Employee SET EmpMonthlyFee= #Value WHERE ID = 1
ELSE
INSERT Employee(ID,EmpDailyFee,EmpMonthlyFee,CompDailyFee,CompMnthlyFee)
VALUES(1,NULL,#value,NULL,NULL)
declare #t table (ID int,Empfee int,monthlyfee int,compdailyfee int,Cmpnymonthlyfee int)
insert into #t (ID,Empfee,monthlyfee,compdailyfee,Cmpnymonthlyfee)
values (1,NULL,12,NULL,NULL),
(1,50,NULL,NULL,NULL),
(1,60,NULL,NULL,NULL)
;with cte as (
select t.ID,t.Empfee,
tt.monthlyfee,
t.compdailyfee,
t.Cmpnymonthlyfee,
ROW_NUMBER()OVER(PARTITION BY t.ID,tt.monthlyfee ORDER BY t.ID,tt.monthlyfee)RN
from #t t
CROSS APPLY #t tt
where t.Empfee IS NULL OR tt.monthlyfee IS NOT NULL)
select C.ID,
C.Empfee,
C.monthlyfee,
C.compdailyfee,
C.Cmpnymonthlyfee from cte c
where c.Empfee IS NOT NULL AND c.monthlyfee IS NOT NULL
Can be done using COALESCE as well.
SELECT T1.ID,
T2.EmpDailyFee,
COALESCE(T1.EmpMonthlyFee , T2.EmpMonthlyFee) EmpMonthlyFee,
COALESCE(T1.CompDailyFee , T2.CompDailyFee) CompDailyFee ,
COALESCE(T1.CompMnthlyFee , T2.CompMnthlyFee) CompMnthlyFee
FROM
(SELECT * FROM Tab WHERE EmpDailyFee IS NULL)T1
JOIN
(SELECT * FROM Tab WHERE EmpDailyFee IS NOT NULL)T2
ON T1.ID = T2.ID
I have gone one step ahead and assumed that values from the first row will take priority if not null(As for the 3rd column in OP). This part can be neglected if not required.

How to ignore a TSQL Where condition when the value of a filter is null in one statement?

How to ignore a where condition when the value of a filter is null in one statement?
-- if #filter1LowerBound is null then
select * from MyTable
-- if #filter1LowerBound is not null then
select * from MyTable
where column1 > #filter1LowerBound
Would that be possible to write one single where condition to handle the above situations?
I know I can CASE WHEN statement when my column is using "=".
or like:
select * from MyTable
where column1 = ISNULL(#filter1LowerBound, column1)
But I am having greater than and less than operators.
I have more greater than and less than filters like that so I'd need to make it work.
How would that be achieved?
Thanks
One way is to combine the clauses like so:
SELECT * FROM MyTable
WHERE (#filter1LowBound IS NULL OR column1 > #filter1LowerBound)
-- AND other conditions here
How about
select * from MyTable where
(#filter1LowerBound is null or column1 > #filter1LowerBound)
Assuming column1 is numeric
select * from MyTable where column1 > ISNULL(#filter1LowerBound, column1-1)
select * from MyTable where column1 < ISNULL(#filter1LowerBound, column1+1)
Similarly, if it's a string
select * from MyTable where column1 > ISNULL(#filter1LowerBound, '')
etc

Resources