SQL INNER JOIN WHEN NULL VALUES - sql

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.

Related

Sql select - how select from other table if is null

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

Check a table against another table SQL

So I have a list of people that I got from table 1.
SELECT UA.user FROM UserAcct UA
I have another table that I need to check against to make sure that the user is not listed in table 2.
LEFT OUTER JOIN AccountsLog AL ON AL.user = UA.user
Ultimately what I am trying to do is make sure that people from table 1 have performed an action on table 2, otherwise their name will be returned. Performing this action will cause their name to show up in table 2. Any help here is greatly appreciated. I am happy to try and elaborate further if this isn't enough information. Thanks!
when you do a left outer join to find records in TABLE A that are not in table B, simply look for NULLs.
So when you LEFT OUTER JOIN the tables on ON AL.user = UA.user, you can then find the missing records with the clause:
WHERE AL.user IS NULL
So if I understand correctly you want Anything from User that not exists in AccountsLog, I think you're on the right track
SELECT UA.user FROM UserAcct UA
LEFT OUTER JOIN AccountsLog AL ON UA.user = AL.user
WHER AL.User is null -- this will give you anything that is on user and not in accountslog
Regards
If your version of SQL supports it, try using Not Exists. Subqueries with NOT EXISTS. I've found it is faster than "left outer joins and filtering for null values".
This will give the users only on UA and not on AL
SELECT UA.user FROM UserAcct UA
MINUS
SELECT AL.user FROM AccountsLog AL
Edit:- For SQL server use EXCEPT instead of MINUS (Supported by Oracle)

SQL JOIN with the same table

I am trying to query in SQL and I can not resolve it.
I have a table tCliente:
What I want to do is a JOIN with the same table to find each pair of clients that lives in the same city.
I try to do this:
SELECT DISTINCT c.codiClien, c.nombreClien, c1.codiClien, c1.nombreClien, c.ciudadClien
FROM tCliente c
INNER JOIN tCliente c1 ON c.ciudadClien = c1.ciudadClien
and get this:
But I should get this:
I know I have to filter data, but I have tried many things and I can not find the solution.
Also, I tried to use GROUP BY but it is not possible. I wanted to group by pair, that is, something like this:
...
GROUP BY c.codiClien, c1.codiClien
But in doing so I get errors in the query. Could someone please help me? Thanks
Note:
When using ON in the INNER JOIN, I would like to know if it is "possible" to do that or should not do it, because the usual thing is to do tb1.id = tb2.id
You must exclude itself on the inner join.
SELECT c.codiClien, c.nombreClien, c1.codiClien, c1.nombreClien, c.ciudadClien
FROM tCliente c
INNER JOIN tCliente c1
ON c.ciudadClien = c1.ciudadClien
AND c.codiClien < c1.codiClien;

Sql join shows null value

I have 2 sql tables mtblSite_Lavel_Budget and mtblExpenditure_Site_Lavel. I want to join them, so I wrote the query below, but one column always give null result although there are values in that field.
Query is as below
select mtblExpenditure_Site_Lavel.SFTI_Id,
mtblExpenditure_Site_Lavel.Site_Lavel_Interventions,
mtblExpenditure_Site_Lavel.Sub_Site_Lavel_Interventions,
mtblExpenditure_Site_Lavel.Bill_No, mtblExpenditure_Site_Lavel.Date_Of_Bill,
mtblExpenditure_Site_Lavel.Eligible_Exp,
mtblExpenditure_Site_Lavel.Non_Eligible_Exp,
mtblExpenditure_Site_Lavel.Total,
mtblExpenditure_Site_Lavel.Physical_Progress,
mtblSite_Lavel_Budget.Sanction_Amount_DPR
from mtblExpenditure_Site_Lavel
left join mtblSite_Lavel_Budget
on mtblExpenditure_Site_Lavel.Sub_Site_Lavel_Interventions= mtblSite_Lavel_Budget.Sub_Site_Lavel_Interventions
WHERE mtblExpenditure_Site_Lavel.SFTI_Id =13
ORDER BY Date_Of_Bill desc
and the result is as below
Please advise regarding the issue.
Try this
from mtblExpenditure_Site_Lavel left join mtblSite_Lavel_Budget on
mtblExpenditure_Site_Lavel.sfti_id = mtblSite_Lavel_Budget.sfti_id
I think its confused becouse you are joining on a string column its always best to join on the id where posible.

TSQL Aggregate function to produce a yes or no flag

I will attempt to explain my problem using a similar but simpler problem. Let's say that I'm writing software for a library, which has a table of Patrons and Books. In addition, it has a CheckOuts table which associates Patrons to any Books (1 per row) that they have checked out.
I'm using MSSQL 2005 and need to build a view or stored procedure that contains two columns, PatronID and HasBook, which needs to be dynamically generated: 1 if the patron has one or more book checked out, and 0 otherwise.
Here is my first attempt at writing a query to do this:
SELECT PatronID, MIN((SELECT 1, COUNT(BookID) FROM CheckOuts WHERE CheckOuts.PatronID = Patrons.PatronID)) AS HasBook
FROM Patrons
The error I'm receiving is:
Cannot perform an aggregate function
on an expression containing an
aggregate or a subquery.
I'm a very new SQL user, so if that query makes you cringe, I would sincerely appreciate any advice you would like to give. I'm very interested in the "right" way to do this.
Well, if you just want to know if the PatronId has any checkout, you can do the following:
SELECT PatronID, CASE WHEN B.PatronId IS NOT NULL THEN 1 ELSE 0 END AS HasBook
FROM Patrons A
LEFT JOIN (SELECT PatronId FROM CheckOuts GROUP BY PatronId) B
ON A.PatronId = B.PatronId
Try this:
SELECT a.PatronID, CASE b.PatronID WHEN NULL THEN 0 ELSE 1 END
FROM Patrons a
LEFT OUTER JOIN Patrons b ON b.PatronID = a.PatronID AND EXISTS (SELECT * FROM CheckOuts c WHERE c.PatronID = b.PatronID)
EDIT: Lamak's solution, using the derived table, may be better than mine. His is probably faster.