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
Related
SQL Masters,
I don't understand part of this query. In the select statement there are what look like independent 'select statements'almost like a function. This code is vendor written Blackbaud CRM. As independent code there is no join in the code for the info they bring into the data set as you can see in the from clause. One last odd item is that in the column aliased Spouse_id the column SPOUSE.RECIPROCALCONSTITUENTID dose not even exist in the table referred to. Any BBCRM people out there that can explain this?
Thanks
select
CONSTITUENT.ID,
CONSTITUENT.ISORGANIZATION,
CONSTITUENT.KEYNAME,
CONSTITUENT.FIRSTNAME,
CONSTITUENT.MIDDLENAME,
CONSTITUENT.MAIDENNAME,
CONSTITUENT.NICKNAME,
(select SPOUSE.RECIPROCALCONSTITUENTID
from dbo.RELATIONSHIP as SPOUSE
where SPOUSE.RELATIONSHIPCONSTITUENTID = CONSTITUENT.ID
and SPOUSE.ISSPOUSE = 1) as [SPOUSE_ID],
(select MARITALSTATUSCODE.DESCRIPTION
from dbo.MARITALSTATUSCODE
where MARITALSTATUSCODE.ID = CONSTITUENT.MARITALSTATUSCODEID) as [MARITALSTATUSCODEID_TRANSLATION]
From
dbo.constituent
left join
dbo.ORGANIZATIONDATA on ORGANIZATIONDATA.ID = CONSTITUENT.ID
where
(CONSTITUENT.ISCONSTITUENT = 1)
These are correlated subqueries. Although there is no explicit JOIN, there is a link to the outer table which behaves like a join (although more constrained than explicit JOINs):
(select SPOUSE.RECIPROCALCONSTITUENTID
from dbo.RELATIONSHIP as SPOUSE
where SPOUSE.RELATIONSHIPCONSTITUENTID = CONSTITUENT.ID AND
-------^ correlation clause connecting to outer table
SPOUSE.ISSPOUSE = 1
) as [SPOUSE_ID],
This behaves like a LEFT JOIN. If no rows match, then the result is NULL.
Note that in this context, the correlated subquery is also a scalar subquery. That means that it returns exactly one column and at most one row.
If the query returned more than one column, you would get a compile-time error on the query. If the query returns more than one row, you will get a run-time error on the query.
I have the following example generated by MS Access for generating results base on table1 without matching table2 on the IP Address columns.
SELECT
Table1.ID, Table1.IP_Address, Table1.Field1
FROM
Table1
LEFT JOIN
Table2 ON Table1.[IP_Address] = Table2.[IP Address]
WHERE
(((Table2.[IP Address]) IS NULL));
While trying to analyze "WHERE (((Table2.[IP Address]) Is Null))" I do not understand how this makes sense, as I interpret it as only return results that are NULL for table2#IP Address. My understanding of WHERE clause is like a filter mechanism for your query and NULL is blank. Can someone help me understand this counter-intuitive statement?
First, a more intuitive way to write the query would use NOT EXISTS:
SELECT Table1.ID, Table1.IP_Address, Table1.Field1
FROM Table1
WHERE NOT EXISTS (SELECT 1
FROM Table2
WHERE Table1.[IP_Address] = Table2.[IP Address]
);
That said, the LEFT JOIN method is perfectly reasonable -- and sensible too.
LEFT JOIN keeps all the rows in the first table (Table1) and matching rows in the second. If there is no match, then the Table2 columns need to be filled with a value -- and for the non-matches, that value is NULL.
The WHERE clause is keeping only these NULL values. Voila! It keeps the rows in Table1 that have no matching value in Table2.
You already mentioned the answer:
generating results base on table1 without matching table2
You use a LEFT JOIN, so you get all the rows from the LEFT table and matching and empty (null) as unmatced rows from the RIGHT table.
The unmatched rows from the RIGHT table will have Table2.[IP Address] equal to Null (since they are unmatching).
So the condition:
WHERE Table2.[IP Address] Is Null
will do exactly what you need:
fetch only these rows from the LEFT table that do not have a match
on the RIGHT table
.
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
I have two tables with same columns, I need to make a select in this two tables, I want to know how is the best way to make this, my select test is:
SELECT
ISNULL(LoteDet.IdLoteDet, LoteDetPg.IdLoteDet) AS Expr1,
ISNULL(LoteDet.IDSac, LoteDetPg.IDSac) AS Expr2,
ISNULL(LoteDet.Comprom, LoteDetPg.Comprom) AS Expr3,
ISNULL(LoteDet.NossoNum, LoteDetPg.NossoNum) AS Expr4,
ISNULL(LoteDet.NossoNumDig, LoteDetPg.NossoNumDig) AS Expr5
FROM
LoteDet
CROSS JOIN
LoteDetPg
WHERE
Expr1 = 500
It's possible to make this ?
How is the better way to execute this kind of select, if not found the value in one table, the value will be in the other table....
------ EDIT
Perhaps create a view is a good alternative to this type of select?
Use COALESCE:
SELECT
COALESCE(LoteDet.IdLoteDet, LoteDetPg.IdLoteDet) AS Expr1,
COALESCE(LoteDet.IDSac, LoteDetPg.IDSac) AS Expr2,
COALESCE(LoteDet.Comprom, LoteDetPg.Comprom) AS Expr3,
COALESCE(LoteDet.NossoNum, LoteDetPg.NossoNum) AS Expr4,
COALESCE(LoteDet.NossoNumDig, LoteDetPg.NossoNumDig) AS Expr5
FROM
LoteDet
CROSS JOIN
LoteDetPg
WHERE
Expr1 = 500
Take a look on this documentation: https://msdn.microsoft.com/pt-br/library/ms190349.aspx
I believe this is going to return you what's called a Cartesian Product. It's the result of an open join, like you have above. That query is going to return TONS of records because you're not specifying how to JOIN the two tables, it's just going to blindly try matching columns. At the very least, add an ON condition to the JOIN so that you can match on IDs/keys. I think what you want is an INNER JOIN with an ON; this will return you all of the matching rows, based on ID/Key.
SELECT
CASE WHEN tbl1.Comprom IS NULL THEN tbl2.Comprom ELSE tbl1.Comprom END AS Expr1
CASE WHEN tbl1.Nossonum IS NULL THEN tbl2.Nossonum ELSE tbl1.Nossonum END AS Expr2
FROM
tbl1 --LoteDet
INNER JOIN tbl2 --LoteDetPg
ON (tbl1.ID = tbl2.ID)
WHERE
Expr1 = 500 --I know I swapped the expression values, use whichever expression you need here
Now, only rows that have a matching ID will return you values and it will use the value from tbl1, unless it is null, then it will use the value from tbl2.
Edit: I know CROSS JOIN turns into an INNER JOIN if a WHERE is specified, but does the WHERE need to include both tables? I feel that the Expr1 = 500 will still produce a Cartesian Product; can someone correct me?
Hi I need to know how to get a result from an query (which connects 2 tables with a outer join) even if my where-clause which points in an empty table get's no result.
Example:
How the result currently looks SQLFiddle.
How the result should looks like SQLFiddle.
When using Outer Join for this example dont use WHERE clause as it treats it as an inner join.
so instead just say AND instead of where
SELECT *
FROM FilledTable
LEFT OUTER JOIN EmptyTable
ON FilledTable.Id = EmptyTable.RefFilledTableId
and EmptyTable.Value = 5
http://sqlfiddle.com/#!2/7a96a/9