Returning 1 or 0 instead of value or null in T-SQL - sql

In my SELECT statement, I join two tables. It's possible that there's no corresponding value in Table2 in which case, my SELECT statement should return NULL for that column. What I want to do is that instead of returning the actual value coming from Table2 I want to return a 1.
I thought I could use ISNULL for this but that function is designed to return the actual value if one exists.
This is what my SELECT statement looks like:
SELECT a.Id, ISNULL(b.PersonId, 0)
FROM Table1 AS a
LEFT OUTER JOIN Table2 AS b ON a.Id = b.Id
Here the PersonId column is of UNIQUEIDENTIFIER type and I don't want to return either a Guid or a 0. Instead, I'd like to return a 1 or a 0.
How can I handle this scenario?

I think you're looking for a CASE EXPRESSION here.
SELECT a.Id, CASE WHEN b.PersonId IS NOT NULL THEN 1 ELSE 0 END
FROM Table1 AS a
LEFT OUTER JOIN Table2 AS b ON a.Id = b.Id

As well as #DaleK's excellent answer, another option is using EXISTS
SELECT
a.Id,
CASE WHEN EXISTS (SELECT 1
FROM Table2 AS b
WHERE a.Id = b.Id)
THEN 1 ELSE 0 END
FROM Table1 AS a
Note that the semantic is different here, as it is a semi-join: the rows are not duplicated if there are multiple matches in Table2

Related

SQL Change named AS colum based on returned values

Looking to use different column values on return after a join, if a value is NOT NULL.
Seems hard to explain but if I have a select statement that names a colum with AS, then Join another valuem and if that is NOT NULL use that new column value in place of the first.
SELECT a.value1 AS value
FROM table a
LEFT JOIN table2 b ON a.id = b.id (assume this is one to one)
What I want is table2 has a column value2, and if that is NOT NULL then make b.value2 AS value
In code would be
if (b.value) {
$value = b.value2;
} else {
$value = a.value1;
}
Use coalesce():
SELECT coalesce(t2.value2, a.value1) AS value
FROM table a LEFT JOIN
table2 b
ON a.id = b.id ;
SELECT
CASE
WHEN b.value2 IS NOT NULL THEN b.value2
ELSE a.value1
END
AS value
FROM table a
LEFT JOIN table2 b ON a.id = b.id

Boolean - Does ID Exist in Table?

I have two tables... A master ID table and a results ID table with only a few IDs from the master table. I'm looking to create the following SQL Query:
Select
A.ID
(Case when B.ID is in A.ID 1 Else 0 End) as is_found
From
master_table as A
LEFT JOIN results_table as B
ON A.ID = B.ID
The resulting table should have all IDs from master table with a boolean column saying if the ID was found in the results table. Thank you for your help!!
I would use case . . . exists:
Select mt.id,
(case when exists (select 1 from results_table rt where rt.id = mt.id) then 1 else 0 end) as is_found
From master_table ;
First, consider the case where results_table will have either zero or one matching row; in this case, the LEFT JOIN will always give one row for each ID, and B.ID will be NULL if there is no corresponding row in results_table.
We can therefore use a simple CASE to test this:
Select
A.ID,
CASE WHEN B.ID IS NOT NULL THEN 1 ELSE 0 END as is_found
From
master_table as A
LEFT JOIN results_table as B
ON A.ID = B.ID
If there may be more than one row in results_table for the same ID, the LEFT JOIN may in turn create several rows, one for each match.
The result of the CASE statement will be the same for all values of A.ID - if there are zero matches, it will occur once with value 0, and if there are one or more, it will always have the value 1. So we can simply take distinct values of the entire query:
Select Distinct
A.ID,
CASE WHEN B.ID IS NOT NULL THEN 1 ELSE 0 END as is_found
From
master_table as A
LEFT JOIN results_table as B
ON A.ID = B.ID

SQL: How to know if a LEFT JOIN returned a row?

Simple problem. I have a simple SQL as thus...
SELECT a.Col1, a.Col2, XXX
FROM table1 AS a
LEFT JOIN table2 as b
ON b.Key1 = a.Key1
What can I put in the 'XXX' above to say something like "does table B exists?".
ie: EXISTS(b) AS YesTable2
I am hoping there is a simpler solution than just using CASE...END statements.
Thanks
You could use ISNULL(b.Key1, 'XXX') Or COALESCE for checking against multiple values for the first non null value.
Pick any column from b that is not allowed to be NULL. If there is a NULL there, the record does not exist. If there is a value there, the record does exist. If every column in b is allowed to be NULL (rare: you should always have something that's not nullable in the primary key) you'll have to build an expression that mimics the JOIN conditions.
I am hoping there is a simpler solution than just using CASE...END statements.
Your guess is spot-on: you can use CASE...END to compare b.Key1 to NULL, like this:
SELECT
a.Col1
, a.Col2
, CASE WHEN b.Key1 IS NOT NULL THEN 1 ELSE 0 END as YesTable2
FROM table1 AS a
LEFT JOIN table2 as b
ON b.Key1 = a.Key1
If you just want to know if a record exists, I would suggest using exists in the select clause:
SELECT a.Col1, a.Col2,
(CASE WHEN EXISTS (SELECT 1 FROM table2 b ON b.Key1 = a.Key1)
THEN 1 ELSE 0
END) as ExistsInTable2
FROM table1 a;
This version will guarantee that you do not get duplicated rows if there are multiple matches in the two tables.

Return value when no record exists on join, oracle

I have simple scenario but struggling at it:
Say I have following 2 tables:
tableA
Acol1 Acol2 Acol3
1 2 3
tableB
Bcol1 Bcol2 Bcol3
1 2 true
A query:
select tabB.Bcol3 from tableA tabA, tableB tabB
where
tabA.Acol1 = tabB.Bcol1
and tabB.Bcol2 = 1
and tabA.Acol1 = 1;
I want my query to return 'false' value since no record exists for this query.
P.S: I cannot user aggregate functions because actually this scenario is part of a larger query with around 15 joins and multiple columns.
So following solution is out of context:
select decode(max(tabB.Bcol3), null, 'FALSE', 'TRUE') from tableA tabA, tableB tabB
where
tabA.Acol1 = tabB.Bcol1
and tabB.Bcol2 = 1
and tabA.Acol1 = 1;
i tried left and right outer joins but in vain.
Use a LEFT JOIN with COALESCE():
select coalesce(tabB.Bcol3, false)
from tableA tabA
left join tableB tabB on tabA.Acol1 = tabB.Bcol2
and tabB.Bcol2 = 1
where tabA.Acol1 = 1;
COALESCE() returns the first non-null value. When the join fails to find a match, the columns of tableB will be null - that's when the default value of false will be returned.
It seems a little-known fact that join conditions may include non-key conditions. By including the extra condition on tabkeB in the join condition, the left join is still effective in returning a row for tableA. If left in the where clause, no row would be returned be ause the where clause is d listed after the join is made and would fail because a null is not going to equal 1.

SQL Case statement to check for NULLS and Non-existent records

I am doing a join between two tables and want to select the columns based on whether they have a record or not. I'm trying to avoid having multiple of the same field and am trying to condense them into single columns. Something like:
Select
id = (CASE WHEN a.id IS NULL THEN b.id ELSE a.id END),
name = (CASE WHEN a.name IS NULL THEN b.name ELSE a.name END)
From Table1 a
Left Join Table2 b
On a.id = b.id
Where a.id = #id
I'd like id to populate from Table1 if a record exists, but if not pull from Table2. The previous code returns no records because there are no NULL values in Table1 so my question is how do I run a check to see if any records even exist? Also if anyone knows of a better way to accomplish what I am trying to do I appreciate guidance and constructive criticism.
EDIT
It looks like COALESCE will work for what I'm trying to accomplish. I'd like to give a little more info on exactly what I am working with and get some advice on whether I am using the best method.
I have a bloated table Table2 and it is in production. I'm working on building new web applications for this system but can't justify a complete database redesign so I am trying to do one "on the fly". I've created a new table Table1 and I am writing stored procedures for the following methods Get(Select), Set(Update), Add(Insert), Remove(Delete). This way, to my code, it will seem that I am working with a single table that is not bloated. My code will simply call one of the SP methods and then the stored procedure will handle the data between the old table and the new. I am currently working on the Get method and I need to check the old table Table2 for a record if it doesn't exist in Table1.
Thanks to the suggestions here my query currently looks like this:
Select
id = coalesce(a.id, b.student_number),
first_name = coalesce(a.first_name, b.first_name),
last_name = coalesce(a.last_name, b.last_name),
//etc
From Table1 a
Full Outer Join Table2 b
On a.id = b.student_number
Where (a.id = #id Or b.student_number = #id)
This works for what I'm trying to accomplish, I'd like to throw it out there to the experienced crowd for any tips or suggestions if there are better or more correct ways to go about this.
Thanks
I suspect your problem may come from doing a left join. Try again using a full outer join, like this:
Select
id = coalesce(a.id, b.id),
name = coalesce(a.name, b.name)
From Table1 a
full outer Join Table2 b
On a.id = b.id
Where a.id = #id
Select id = coalesce(a.id, b.id),
name = coalesce(a.name, b.name)
From Table2 b
Left Join Table1 a On a.id = b.id
Where b.id = #id
You may need to use ISNULL or CASE instead of COALESCE depending on your database platform.
First, you don't need a case statement for that:
Select ISNULL(a.id,b.id) AS id, ISNULL(a.name,b.name) AS name,
From Table1 a
Left Join Table2 b
On a.id = b.id
Where a.id = #id
Second, if I get it right, the id field can contain nulls, and in that case you are screwed. I mean, the ID is a unique value that identify a row, if it can be null, you can't identify that row.
But if what you want is getting records from Table1 and Table2 and avoid duplicates, a simple UNION will work fine, since it discards duplicates:
select id, name
from Table1
where id = #id
union
select id, name
from Table2
where id = #id
You could do something like:
select id, name from Table1 a where a.id not in (select id from Table2)
UNION
select id, name from Table2 b
This would give you all the records from table1 that didn't have a corresponding match in table2 plus all of table2's records. The union would then combine the results.
In your first CASE statement, a.id and b.id will always be same value, except for instances in which a.id has a value and b.id generates a NULL value because of the LEFT JOIN. There will never be a row in the result set with a NULL a.id value and a non-NULL b.id value. You could just use a.id for this column.
For the second CASE statement, you may find the name column in either or both tables with a value (and, of course, the values may be different). You said you want to "condense" the these column values; the SQL function for that is COALESCE:
COALESCE(a.id, b.id)
which returns the first non-NULL value (a.id if it isn't NULL, otherwise b.id). It won't tip you off to different names in the two tables.