Not equal Null not working in sql server - sql

I have a query given below
SELECT
B.[Date],
B.[Detail],
B.[Number],
B.[Total],
CASE WHEN B.[ApId] != null THEN Ap.Name ELSE B.[Name]END Name,
FROM [Bacs] B
LEFT JOIN Table ap ON b.ApId= ap.Id
In the Case When query I am trying to return the Name based on the b.ApId value.
But even if b.ApId is not null I am getting B.Name instead of Ap.Name.
Can anyone point out where I am going wrong.

!= will evaluate for values, while NULL is not a value.
So you have to either use IS NULL or IS NOT NULL to compare nulls.
SELECT
B.[Date],
B.[Detail],
B.[Number],
B.[Total],
CASE WHEN B.[ApId] is not null THEN Ap.Name ELSE B.[Name]END Name,
FROM [Bacs] B
LEFT JOIN Table ap ON b.ApId= ap.Id

Use IS NOT NULL, IS NULL to compare with NULL value, Or use ISNULL, COALESCE function
SELECT
B.[Date],
B.[Detail],
B.[Number],
B.[Total],
CASE WHEN B.[ApId] IS NOT NULL THEN Ap.Name ELSE B.[Name] END Name
-- ISNULL(Ap.Name, B.[Name]) as Name
-- COALESCE(Ap.Name, B.[Name],'') as Name
FROM [Bacs] B
LEFT JOIN Table ap ON b.ApId= ap.Id

Related

Fetch data from 3 three tables whichever is not null

I am trying to find the available address details from three tables.
When table 1 has the address details then get it from table1
If table 1 address has null value then consider table2,
If table 2 address has null value then consider table3, else display table1 address (null)
There are foreign keys in table 1 which can be used to join table 2 and 3 but they can be null as well in which case only data from table 1 to be considered.
In my query, I am able to join the tables when the foreign keys are available but in case they are null, the query doesn’t work!
I am not sure if I can add a ‘Case’ statement to ignore the ‘Join’ conditions in case the foreign keys are null.
Can someone please assist?
My Query is below :
SELECT donor.donor_num,
CASE
--WHEN donor.addr1 IS NULL THEN paraddress.addr1
--WHEN paraddress.addr1 IS NULL THEN enrparaddr.addr1
WHEN donor.addr1 IS NULL THEN enrparaddr.addr1
ELSE donor.addr1
END AS Address1,
CASE
--WHEN donor.addr2 IS NULL THEN paraddress.addr2
--WHEN paraddress.addr2 IS NULL THEN enrparaddr.addr2
WHEN donor.addr2 IS NULL THEN enrparaddr.addr2
ELSE donor.addr2
END AS Address2
FROM donor
JOIN enrparaddr ON enrparaddr.par_code = donor.enrol_code
--JOIN paraddress ON paraddress.par_code = donor.par_code
WHERE donor_num = '17206'
Please see attached image for the three tables
You can try below - using FULL OUTER JOIN & coalesce() function
SELECT donor.donor_num,
coalesce(donor.addr1,paraddress.addr1,enrparaddr.addr1) AS Address1,
coalesce(donor.addr2,paraddress.addr2,enrparaddr.addr2) AS Address2
FROM donor
FULL OUTER JOIN enrparaddr ON enrparaddr.par_code = donor.enrol_code
FULL OUTER JOIN paraddress ON paraddress.par_code = donor.par_code
WHERE donor_num = '17206'
SELECT donor.donor_num,CASE WHEN donor.addr1 IS NULL
THEN enrparaddr.addr1
ELSE donor.addr1
END AS Address1,
CASE WHEN donor.addr2 IS NULL
THEN enrparaddr.addr2
ELSE donor.addr2
END AS Address2
FROM donor
left join enrparaddr ON enrparaddr.par_code = donor.enrol_code
WHERE donor_num = '17206'
I would recommend:
SELECT d.donor_num,
coalesce(d.addr1, pp.addr1, epe.addr1) AS Address1,
coalesce(d.addr2, pp.addr2, epe.addr2) AS Address2
FROM donor d LEFT JOIN
paraddress pp
ON pp.par_code = d.par_code LEFT JOIN
enrparaddr epe
ON epe.par_code = d.enrol_code AND
pp.par_code IS NULL
WHERE d.donor_num = 17206 -- do not use single quotes for numbers
Notes:
You want a LEFT JOIN because you want all rows in donors.
You should be joining the tables in the order used for the COALESCE().
The second JOIN condition can be limited to cases where the first does not match.
Number constants should not use single quotes.
You can do this with simple Case .. When Statement:
Select Case
When A.ID is NULL And B.ID is NULL And C.ID is NULL Then -- when all columns contain null
NULL
When A.ID is NULL And B.ID is NULL Then
C.ID
When B.ID is NULL and C.ID is NULL Then
A.ID
When A.ID is NULL And C.ID is NULL Then
B.ID
End As ID
From A, B, C

Null value is considered an existing value

I have a validation into if conditional like:
IF(EXISTS
(SELECT TOP 1 [TaskAssignationId]
FROM [Task] AS [T]
INNER JOIN #TaskIdTableType AS [TT] ON [T].[TaskId] = [TT].[Id]
))
But it returns NULL value because TaskAssignationId is NULL so in consequence IF condition it's true because it exist with NULL value, but I don't want to consider NULL as a value. How can add an exception of nulls? Regards
If you don't want to include rows where [TaskAssignationId] is null then add that to a WHERE clause.
IF(EXISTS
SELECT TOP 1 [TaskAssignationId]
FROM [Task] AS [T]
INNER JOIN #TaskIdTableType AS [TT] ON [T].[TaskId] = [TT].[Id]
WHERE [TaskAssignationId] is not null
))
Exists works like "Did the (sub)query return more than zero (correlated) rows" not "did the (sub)query return a non null value"
These are perfectly valid exists:
SELECT * FROM person p
WHERE EXISTS (SELECT null FROM address a WHERE a.personid = p.id)
SELECT * FROM person p
WHERE EXISTS (SELECT 1 FROM address a WHERE a.personid = p.id)
SELECT * FROM person p
WHERE EXISTS (SELECT * FROM address a WHERE a.personid = p.id)
It doesn't matter what values you return, or how many columns, exists cares whether the rowcount is 0 or greater when determining whether results exist
Hence you have to make sure your (sub)query returns no rows if you want the exists check to fail. If Addresses that have a null type are unacceptable, the (sub)query has to exclude them with WHERE a.type IS NOT NULL so that only rows with a non null type are considered
There's also little point doing a TOP 1 in the (sub)query; the optimiser knows that the only condition it cares about is 0 or not-0 rows, so it automatically do a TOP 1 (i.e. it will stop retrieving data when it knows there is at least one row)
If you want to check the existence then no need to assign the column name, you can use select 1
IF(EXISTS
SELECT TOP 1 1
FROM [Task] AS [T]
INNER JOIN #TaskIdTableType AS [TT] ON [T].[TaskId] = [TT].[Id]
))
begin
----code---
end

Using select case on a left join?

I have used a left join on two of my tables. Now I want to use case to identify the records from my left table who don't have a match in the right table. Such records exist and have a null value in the 'id_zeus' column of my join, however when I execute the case, it is as these fields don't exist. Where am I going wrong ? I get "Present" in all my column Disturbance. I am using Oracle SQL developer.
SELECT
CASE DP.ID_PRB
WHEN NULL
THEN 'Absence'
ELSE 'Present' END as Disturbance,
FROM
FIRE.WSITE WI
LEFT JOIN
(SELECT DISTINCT
DPL.ID_PERT as ID_PRB
FROM FIRE.DEPPLAN DPL
GROUP BY DPL.ID_PERT
) DPL
ON WI.ID_PERT = DP.ID_PERT
What is const? You don't seem to need it. The SELECT DISTINCT and GROUP BY are redundant, so use only one of them. And your alias on the subquery is incorrect.
But your problem is the comparison to NULL. It doesn't even match when doing a comparison as you are doing in CASE. You need to use IS NULL:
SELECT (CASE WHEN DP.ID_PRB IS NULL THEN 'Absence' ELSE 'Present'
END) as Disturbance,
FROM FIRE.WSITE WI LEFT JOIN
(SELECT DISTINCT DPL.ID_PERT as ID_PRB
FROM FIRE.OSI_DEVIATION_PLANS DP
) DP
ON WI.ID_PERT = DP.ID_PERT;
This query would commonly be written as:
SELECT (CASE WHEN NOT EXISTS (SELECT 1
FROM FIRE.OSI_DEVIATION_PLANS DP
WHERE WI.ID_PERT = DP.ID_PERT
)
THEN 'Absence' ELSE 'Present'
END) as Disturbance,
FROM FIRE.WSITE WI ;
This offers more opportunities for optimization.

How to return Yes or No if nested query has result or not in SQL Server?

I have a stored procedure with a nested query that checks whether "category" from the main table matches a "category" in a sub table.
So there can either be one match or none.
How can I return Yes if there is a match and the sub query returns something and No if there is no match and the sub query returns nothing ?
I tried the following which works in general but only if there is a match as otherwise this returns nothing.
My SQL (shortened):
SELECT A.categoryID,
A.category,
A.[description],
(
SELECT 'Yes' AS subscribed
FROM MOC_Categories_Subscribers D
WHERE D.category = A.category
FOR XML PATH(''), ELEMENTS, TYPE
)
FROM MOC_Categories A
If subquery doesn't return any rows then your result will be NULL. Thus you need to check it. In SQL Server you can do this by using functions ISNULL and COALESCE, it depends on version that you're using
SELECT A.categoryID,
A.category,
A.[description],
COALESCE((SELECT TOP 1 'Yes'
FROM MOC_Categories_Subscribers D
WHERE D.category = A.category), 'No') AS Result
FROM MOC_Categories A
SELECT A.categoryID,
A.category,
A.[description],
(
SELECT
case
when count(subscribed) > 0 then 'Yes'
else 'No'
end
FROM MOC_Categories_Subscribers D
WHERE D.category = A.category
)
FROM MOC_Categories A
You can use an outer join, which returns null values if there is no match. Combine with a case to convert to a yes/no value:
SELECT A.categoryID,
A.category,
A.[description],
subscribed = CASE
WHEN D.category IS NOT NULL THEN 'Yes'
ELSE 'No'
END,
FROM MOC_Categories A
LEFT OUTER JOIN MOC_Categories_Subscribers D
ON D.category = A.category

how can i substitute a NULL value for a 0 in an SQL Query result

SELECT EmployeeMaster.EmpNo, Sum(LeaveApplications.LeaveDaysTaken) AS LeaveDays
FROM EmployeeMaster FULL OUTER JOIN
LeaveApplications ON EmployeeMaster.id = LeaveApplications.EmployeeRecordID INNER JOIN
LeaveMaster ON EmployeeMaster.id = LeaveMaster.EmpRecordID
GRoup BY EmployeeMaster.EmpNo
order by LeaveDays Desc
with the above query, if an employee has no leave application record in table LeaveApplications, then their Sum(LeaveApplications.LeaveDaysTaken) AS LeaveDays column returns NULL. What i would like to do is place a value of 0 (Zero) instead of NULL. I want to do this because i have a calculated column in the same query whose formular depends on the LeaveDays returned and when LeaveDays is NULL, the formular some how fails. Is there away i can put 0 for NULL such that that i can get my desired result.
SELECT EmployeeMaster.EmpNo, ISNULL(Sum(LeaveApplications.LeaveDaysTaken),0) AS LeaveDays
FROM EmployeeMaster FULL OUTER JOIN
LeaveApplications ON EmployeeMaster.id = LeaveApplications.EmployeeRecordID INNER JOIN
LeaveMaster ON EmployeeMaster.id = LeaveMaster.EmpRecordID
GRoup BY EmployeeMaster.EmpNo
order by LeaveDays Desc
You may want to use ISNULL
ISNULL(SUM(LeaveApplications.LeaveDaysTaken), 0) AS LeaveDays
Use the isnull function.