SQL alter a column if exists - sql

I have two tables. A and B. I'm trying to figure out a way to add a column in my select query that returns true or false as to whether or not there exists a record in B.
Table A
ID Title
1 A
2 B
3 C
4 D
5 E
Table B
ID Detail
3 foo
4 foo
4 bar
4 barfood
I want to basically "SELECT ID, Title, (Exists?) FROM A" to return
ID Title Exists
1 A False
2 B False
3 C True
4 D True
5 E False
Table A's ID column will always be unique. Table B's ID column can have zero, one, or many relating back to table A's ID. I don't care about the detail in table B, I just want to know if there is at least one record in table B that relates to table A's ID.
I'm new to SQL and I've been searching for ways to use 'if exists' or any other way to parse this out but I'm not really finding what I'm looking for.

If you're adding a column named 'Exists' temporary then try this
select a.id, a.title,case when a.id=b.id then 'True' else 'False' end as Exists
from A a left outer join B b
on a.id = b.id
If you've alredy added Exists column to table then
select a.id, a.title,Exists=(case when a.id=b.id then 'True' else 'False')
from A a left outer join B b
on a.id = b.id

There are probably more efficient ways to accomplish it, but a combination of count and a case statement will do the trick:
select ID, Title,
case when
(select count(1) from B where ID = A.ID) = 0 then 'False'
else 'True'
end as 'Exists'
from A
SQLFiddle link

if you left join table B then you'll get that information
select a.id, a.title,
case
when b.id is null then 'false'
else 'true'
end
from a
left outer join b on a.id = b.id
group by a.id, a.title

Related

Create column that combines two columns by ifelse statementet in SQL

In SQL I am trying to combine create a column id_main2 (after a right join) that is equal the value of column id_main (coming from a) if not NULL and the value of id (coming from b) if id_main is NULL.
Below is the join code followed by the desired output. How can I create this id_main2 column?
SELECT * FROM a
RIGHT JOIN b on a.id = b.id;
id_main id boy id girl id_main2
10 1 Alex 1 Alice 10
11 2 Bruce 2 Brunet 11
NULL NULL NULL 5 Emma 5
NULL NULL NULL 6 Fabia 6
I think you just want coalesce():
select a.*, b.*,
coalesce(a.id_main, b.id)
from b left join
a
on a.id = b.id;
I strongly prefer left join to right join, so I rearranged the tables in the from clause.
You can either use coalesce()
select
coalesce(a.id_main, b.id) as id_main2
from a
right join b on a.id = b.id;
or case when
select
case when a.id is not null then a.id
else b.id end as id_main2
from a
right join 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

Return all inactive items from Table B for each item in Table A

Not sure if I can explain this well in words..
I want to find all items in Table B that have ALL items inactive for each item in Table A. Let's say Table A just has column "item" and Table B has columns "item" and "active"
Table A Table B
A A | 1
A A | 1
A B | 1
B B | 0
B C | 0
B C | 0
C D | 0
C E | 1
D
E
F
In that example, it should return C and D.
I managed to join tables A and B together with a group by clause but not sure where to go from there. Tried looking around and only found answers where the other table's value doesn't exist so you can use "NOT IN" but that doesn't seem to work here.
Any help would be appreciated!
You can join the tables and use the HAVING clause to make the comparison like this:
SELECT ta.Item
FROM TableA tA
LEFT JOIN TableB tB
ON tA.Item=tB.Item
GROUP BY tA.Item
HAVING SUM(tB.Inactive)=COUNT(tb.Inactive)
This would give you a distinct list of Items in TableA
The above query assumes 1 is Inactive and 0 is Active. If your data is opposite (which it looks like it is), you could instead say:
SELECT ta.Item
FROM TableA tA
LEFT JOIN TableB tB
ON tA.Item=tB.Item
GROUP BY tA.Item
HAVING SUM(tB.Inactive)=0
This would also return Item F as it doesn't have a value in table b to SUM. Just flip the LEFT JOIN to an INNER JOIN if you don't want Item F to return.
If you need to return back all instances in TableA, you could use a subquery and join to that:
SELECT ta.Item
FROM TableA tA
LEFT JOIN (SELECT ITEM, SUM(ACTIVE) Sum0 FROM TableB GROUP BY ITEM)tB
ON tA.Item=tB.Item
WHERE tB.Sum0 = 0
/*or tB.Sum0 is null would give you Item F*/
Use NOT EXISTS:
select distinct a.item
from table_A a
where not exists (select 1 from table_B b where b.item = a.item and b.status = 1);
I believe you would just need to join the tables together on table name and filter to only value of 0 on the active column.
SELECT B.*
FROM TableA A INNER JOIN TableB B ON A.item = B.item
WHERE B.active = 0
Does that get you what you need?

Run a query on Parent to show records of only one child table

I've 3 tables, viz A, B & c.
B & C has forign key of A.
Now I want to run a query on A, in such a way, that only records of B are returned.
That is, I want to exclude all the results of C and show only results of B, when a query is executed on all the records of A.
Hope, I've the question makes sense.
If you want to return all records of A and any matching records from B then something a left outer join is appropriate:
SELECT a.*, b.*
FROM a, b
WHERE a.id = b.id
This will return each record from A and populate values from B where there is a match. This will also return multiple rows for records that occur in A if there are multiple rows in B that match.
Just because there is a foreign key in C that references something in table A, it won't be returned unless you use it in your query.
If you just want to return all records from B when the foreign key appears in A then maybe you want:
SELECT *
FROM B
WHERE B.id in (SELECT id FROM A)
AND B.id not in (SELECT id FROM C)
or
SELECT *
FROM B
WHERE EXISTS (SELECT 1 FROM A JOIN B on A.id = B.id)
AND NOT EXISTS (SELECT 1 FROM C JOIN B on C.id = B.id)
All these assume that id is the key which is common.
Is this what you want?
select a.*
from a
where exists (select 1 from b where b.aid = a.aid) and
not exists (select 1 from c where c.aid = c.aid);

Searching Unique Id in Multiple Tables

I have a Scenario where i am required to search unique id in Mutiple tables and assign a level based on where it exist.
Table Hierarchy
TableA
TableB
TableC
Table B holds primary key of table A and Table C holds the Primary of TableB
I need to have a function that takes Id as parameter and Searches that Id in this Table Hierarchy and Return Level i-e If it exist in TableA Level should be One. If it exists in TableB Level should be 2 and if it's in TableC then level should be 3
Here's one way:
SELECT CASE WHEN EXISTS(SELECT 1 FROM TableC WHERE id = #id) THEN '3'
WHEN EXISTS(SELECT 1 FROM TableB WHERE id = #id) THEN '2'
WHEN EXISTS(SELECT 1 FROM TableA WHERE id = #id) THEN 'One'
END AS "Level"
Assuming you want to return the highest level, 3 being the highest for TableC, then something like this should work using the CASE statement:
SELECT
CASE
WHEN C.Id IS NOT NULL THEN 3
WHEN B.Id IS NOT NULL THEN 2
WHEN A.Id IS NOT NULL THEN 1
END as Level
FROM (SELECT #Id as Id) H
LEFT JOIN TableA A ON H.Id = A.Id
LEFT JOIN TableB B ON H.Id = B.Id
LEFT JOIN TableC C ON H.Id = C.Id
Where #Id is the Id of the value you are searching for, for example SELECT 1 as Id.
Good luck.
You need a query that looks like this:
SELECT 1 FROM TableA WHERE id = {0}
UNION ALL
SELECT 2 FROM TableB WHERE id = {0}
UNION ALL
SELECT 3 FROM TableC WHERE id = {0}
The advantage to this over "WHEN" statements is that a) I don't like WHEN statements, and b) if a key exists in multiple tables, this returns a record for each, giving you the opportunity to build program logic around handling that case.