Sql select - how select from other table if is null - sql

I have a view which returns me some nulls values for the columns b.emissor and B.indexador. In case of null, I need to find this values first in table TB_CAD_RF and, if still nulls, I need to query TB_CAD_RF_2.
I try the logic below but its not working. Also tried to think something with case statements but cant figure it out.
Anyone could help me please?
select A.NM_ATIVO, B.EMISSOR, B.INDEXADOR from VW_POSICAO as A
LEFT JOIN
TB_CAD_RF B on A.NM_ATIVO = B.CODIGO
where a.NM_EMISSOR is null
as C LEFT JOIN (
select C.EMISSOR, C.INDEXADOR from TB_CAD_RF_2 as D ON B.NM_ATIVO = C.CODIGO where C.EMISSOR is null)

This pattern:
SELECT
COALESCE( first.choice, second.choice, third.choice) as a
FROM
first
LEFT JOIN second on first.id = second.id
LEFT JOIN third on second.id = third.id
Coalesce returns the first non null passed into it, scanning from left to right

Here is one way. Always join both and coalesce the fields in the order of desired results.
select A.NM_ATIVO,
EMISSOR = COALESCE(A.EMISSOR,B.EMISSOR),
INDEXADOR=COALESCE(A.INDEXADOR,B.INDEXADOR)
from VW_POSICAO A
LEFT JOIN TB_CAD_RF B on A.NM_ATIVO = B.CODIGO
LEFT JOIN TB_CAD_RF_2 D ON A.NM_ATIVO =D.CODIGO

Case when ISNULL((select * from table1) , (select * from table2) ) else select...
ISNULL is like an IIF statement, but if query field returns a null value, it tries the alternate query or you can set an alternate value.
Syntax may be a bit off, haven't written this query in a while, but it should put you on the right path. Google sql ISNULL

Related

where clause in nested isNull query giving unexpected result

The below query returns around 200000 results.
The working of nested where clause in this query is not very clear i.e where is it coming in the picture ?
If I comment out the where clause inside the isNull then I get 0 results, which is fine and expected as the Max(invoiceID) is not null after join.
select * from CustomerServices where isNull((
SELECT MAX(invoiceid)
FROM Invoices
LEFT JOIN InvoicesHistory
ON InvoicesHistory.ServiceHistoryID = Invoices.ServiceHistoryID
WHERE serviceID = Invoices.serviceID
),0)=0
Please let me know if you want me to add more information.
I think you just want not exists:
select cs.*
from CustomerServices cs
where not exists (select 1
from Invoices i left join
InvoicesHistory ih
on ih.ServiceHistoryID = i.ServiceHistoryID
where cs.serviceID = i.serviceID
);
In your case, the nested WHERE clause is not doing anything. It is equivalent to:
Invoices.serviceID = Invoices.serviceID
by the scoping rules in SQL. In all likelihood, this is intended to be a correlation clause and hence needs a qualified column name.

SQL INNER JOIN WHEN NULL VALUES

Hello guys :) I have a table with 2 fields that are FK from another table. Those fields are idAdviceOwner and idAdviceNotifier. However, only one of them is with a value. I want to validate where or not it has a NULL value in order to choose the other field...Basically I've done this, of course is not running but that's the Idea... hope you guys help me out.
select *from notification n
inner join user u
on (n.idUserNotifier=u.idUser)
inner join advice a on (case WHEN n.idAdviceOwner IS NOT NULL
THEN n.idAdviceOwner=a.idAdvice
else n.idAdviceNotifier=a.idAdvice )
where n.idUser=8
select * from notification n
inner join user u
on (n.idUserNotifier=u.idUser)
inner join advice a on case WHEN n.idAdviceOwner IS NOT NULL
THEN n.idAdviceOwner else n.idAdviceNotifier END = a.idAdvice
where n.idUser=8;
Your idea was right but CASE-WHEN-ELSE-END returns an expression, not a condition. That's why you received the error.
You don't say what the error is, and I don't have a SQL engine handy to test on (I am on the road), but I think what you are trying to do here should basically work, except you probably need to do something along the lines of
... on a.idAdvice = (case WHEN n.idAdviceOwner IS NOT NULL
THEN n.idAdviceOwner
else n.idAdviceNotifier)
Another way is to join to advice twice in your query, once with idAdviceOwner, and once with idAdviceNotifier, and then use COALESCE or similar to combine the fields from the two results.

how the sub select query in the case clause get the parameter value of the main query

I have two tables both has id columns, but TableA.id is char, and TableB.id is int. now I want to join two tables, but the problem is there are some string in A.id can't be converted to int. Here is the query I wrote
SELECT
case
when Column1 is null
then (select Surname from TableB
where TableA.id = TableB.id
)
else Column1
end
FROM TableA
GO
the sub select query returns a bunch of records, so my question is that is it possible to run that subquery with the current TableB.id? I am not sure if i explained this clearly, how the subquery get the TableB.id's value of the main query. Thanks
I'm not sure I'm following you, but it sounds like the crux of the problem is that you are trying to join on ID, but they are different field types. Perhaps something like:
SELECT
COALESCE(TableA.Column1, TableB.Surname)
FROM
TableA
LEFT OUTER JOIN TableB On
TableA.ID = Cast(TableB.ID AS Char(64))
I was just taking a guess at the CHAR size, but I assume that's ample. Also I'm not sure what DB you are working on so the syntax may need a bit tweaked.
There is a feature that can do that. It's called a Correlated Subquery, although I'm not sure they work inside case statements.

Selecting NVL With Joins

I am trying to write an SQL statement that will pull the value from one table and its corresponding value from another. This works fine unless one of the values that are being used in a join are null, then it returns nothing. I would like the script to return a value (like 'Nothing') in the event the join is null. Is this possible? I know I can use NVL in the select but what about the join? Here is my script:
SELECT
i.equip_pk,
i.request_pk,
MY_ALIAS.EQUIP_ALIAS_ID
FROM
tableOne i
JOIN table2 MY_ALIAS ON (i.EQUIP_PK = MY_ALIAS.EQUIP_PK)
WHERE i.request_pk=:requestPk
I am using Oracle 10g but this script is not going to be used as PL/SQL.
Thanks for any help
jason
You can use a LEFT JOIN. That will return all rows from tableOne, and when it can't find a match in the second table, it will return null. Then you can use NVL like you mentioned.
SELECT
i.equip_pk,
i.request_pk,
NVL(MY_ALIAS.EQUIP_ALIAS_ID, 'Nothing here')
FROM tableOne i
LEFT OUTER JOIN table2 MY_ALIAS ON (i.EQUIP_PK = MY_ALIAS.EQUIP_PK)
WHERE i.request_pk=:requestPk
If you're expecting nulls from equip_pk, you can apply NVL to that to. Even if it's null, the LEFT JOIN will still produce the proper result.
SELECT
NVL(i.equip_pk, 'Nothing'),
NVL(i.request_pk, 'Nothing)',
MY_ALIAS.EQUIP_ALIAS_ID
FROM
tableOne i
FULL JOIN table2 MY_ALIAS ON (i.EQUIP_PK = MY_ALIAS.EQUIP_PK)
WHERE i.request_pk=:requestPk

"Invalid use of Null" suddenly from 2nd left join

I have this SQL query in Access, which works fine:
SELECT TableA.FieldA As [Code],
Count(TableA.FieldC) AS [Count]
FROM ((MainTable)
LEFT JOIN TableA ON MainTable.FieldB = TableA.FieldB)
WHERE (((MainTable.DateOf)>=#1/1/2012#))
AND Clng(TableA.FieldA) >= 119593451
AND Clng(TableA.FieldA) <= 119593461
GROUP BY TableA.FieldA;
But when I try another left join, like so:
SELECT TableA.FieldA As [Code],
Count(TableA.FieldC) AS [Count]
FROM ((MainTable)
LEFT JOIN TableA ON MainTable.FieldB = TableA.FieldB)
LEFT JOIN TableB ON TableA.FieldD = TableB.FieldD
WHERE (((MainTable.DateOf)>=#1/1/2012#))
AND Clng(TableA.FieldA) >= 119593451
AND Clng(TableA.FieldA) <= 119593461
GROUP BY TableA.FieldA;
I am using the parenthesis in the FROM claused based on this: http://nm1m.blogspot.com/2007/10/multiple-left-joins-in-ms-access.html
It gives the error Invalid use of Null, which doesn't make sense to me as I'm performing no null check etc. What is the problem here? I'm trying to pull a field in TableB to display (but did not put it in the select section yet).
Access likes its parentheses. Add more parentheses around joins.
The CLng function requires a non-null value. You can fix this with CLng(Nz(TableA.FieldA, "0")) >= 119593451. Though, if the field is numeric, why on earth would you make it text to begin with? This is a serious problem that I highly recommend fixing immediately (if at all possible) by changing the data type to a numeric one.
But you have another problem. It is meaningless to LEFT JOIN to a table if you then in the WHERE clause put a condition, as you are doing in your query! Either change to an INNER JOIN or put your conditions on TableA into the ON clause of the LEFT JOIN. If Access won't allow this syntax, then change to a derived table:
SELECT
TableA.FieldA As [Code],
Count(TableA.FieldC) AS [Count]
FROM
(
(
(MainTable)
LEFT JOIN (
SELECT * FROM TableA
WHERE
Clng(Nz(TableA.FieldA, "0")) >= 119593451
AND Clng(Nz(TableA.FieldA, "0")) <= 119593461
) TableA ON MainTable.FieldB = TableA.FieldB
)
LEFT JOIN TableB ON TableA.FieldD = TableB.FieldD
)
WHERE (((MainTable.DateOf)>=#1/1/2012#))
GROUP BY TableA.FieldA;
Note: adding WHERE TableA.FieldA IS NOT NULL may work but may not work. In Access it could be 100% safe but such a query in SQL Server would NOT be safe because there is no guaranteeing the order of conditions being applied. Obviously, in SQL Server you can convert to an integer even when NULL and there is no CLng function, but the point is still valid: do not get in the habit of relying on some imagined order of WHERE conditions protecting you from invalid type conversion: instead you must handle the invalid type conversion inside the expression that can error--that is best practice.